]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blobdiff - app/src/main/java/com/stoutner/privacybrowser/activities/MainWebViewActivity.java
Fix audio and video sometimes playing after a tab is closed. https://redmine.stoutne...
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / activities / MainWebViewActivity.java
index 422bb5ef3e2da4df60e60bf0de128c19577bf222..4180e28c31f5c2c574f8dfa7b529194b41fcb9c9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2015-2020 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2015-2021 Soren Stoutner <soren@stoutner.com>.
  *
  * Download cookie code contributed 2017 Hendrik Knackstedt.  Copyright assigned to Soren Stoutner <soren@stoutner.com>.
  *
@@ -321,14 +321,20 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     private String saveWebpageFilePath;
 
     // Declare the class views.
+    private FrameLayout rootFrameLayout;
     private DrawerLayout drawerLayout;
+    private RelativeLayout mainContentRelativeLayout;
     private AppBarLayout appBarLayout;
     private Toolbar toolbar;
+    private RelativeLayout urlRelativeLayout;
+    private EditText urlEditText;
+    private ActionBar actionBar;
     private LinearLayout findOnPageLinearLayout;
     private LinearLayout tabsLinearLayout;
     private TabLayout tabLayout;
     private SwipeRefreshLayout swipeRefreshLayout;
     private ViewPager webViewPager;
+    private FrameLayout fullScreenVideoFrameLayout;
 
     // Declare the class menus.
     private Menu optionsMenu;
@@ -445,7 +451,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         setContentView(R.layout.main_framelayout);
 
         // Get handles for the views.
+        rootFrameLayout = findViewById(R.id.root_framelayout);
         drawerLayout = findViewById(R.id.drawerlayout);
+        mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout);
         appBarLayout = findViewById(R.id.appbar_layout);
         toolbar = findViewById(R.id.toolbar);
         findOnPageLinearLayout = findViewById(R.id.find_on_page_linearlayout);
@@ -453,6 +461,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         tabLayout = findViewById(R.id.tablayout);
         swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
         webViewPager = findViewById(R.id.webviewpager);
+        fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
 
         // Get a handle for the navigation view.
         NavigationView navigationView = findViewById(R.id.navigationview);
@@ -476,15 +485,19 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         appCompatDelegate.setSupportActionBar(toolbar);
 
         // Get a handle for the action bar.
-        ActionBar actionBar = appCompatDelegate.getSupportActionBar();
+        actionBar = appCompatDelegate.getSupportActionBar();
 
-        // This is needed to get rid of the Android Studio warning that the action bar might be null.
+        // Remove the incorrect lint warning below that the action bar might be null.
         assert actionBar != null;
 
         // Add the custom layout, which shows the URL text bar.
         actionBar.setCustomView(R.layout.url_app_bar);
         actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
 
+        // Get handles for the views in the URL app bar.
+        urlRelativeLayout = findViewById(R.id.url_relativelayout);
+        urlEditText = findViewById(R.id.url_edittext);
+
         // Create the hamburger icon at the start of the AppBar.
         actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.open_navigation_drawer, R.string.close_navigation_drawer);
 
@@ -642,11 +655,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         updatePrivacyIcons(true);
     }
 
-    // `onResume()` runs after `onStart()`, which runs after `onCreate()` and `onRestart()`.
+    // `onStart()` runs after `onCreate()` or `onRestart()`.  This is used instead of `onResume()` so the commands aren't called every time the screen is partially hidden.
     @Override
-    public void onResume() {
+    public void onStart() {
         // Run the default commands.
-        super.onResume();
+        super.onStart();
 
         // Resume any WebViews.
         for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
@@ -678,9 +691,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
         // Reapply any system UI flags and the ad in the free flavor.
         if (displayingFullScreenVideo || inFullScreenBrowsingMode) {  // The system is displaying a website or a video in full screen mode.
-            // Get a handle for the root frame layouts.
-            FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
-
             /* Hide the system bars.
              * SYSTEM_UI_FLAG_FULLSCREEN hides the status bar at the top of the screen.
              * SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN makes the root frame layout fill the area that is normally reserved for the status bar.
@@ -690,15 +700,19 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             rootFrameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
                     View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
         } else if (BuildConfig.FLAVOR.contentEquals("free")) {  // The system in not in full screen mode.
+            // Get a handle for the ad view.  This cannot be a class variable because it changes with each ad load.
+            View adView = findViewById(R.id.adview);
+
             // Resume the ad.
-            AdHelper.resumeAd(findViewById(R.id.adview));
+            AdHelper.resumeAd(adView);
         }
     }
 
+    // `onStop()` runs after `onPause()`.  It is used instead of `onPause()` so the commands are not called every time the screen is partially hidden.
     @Override
-    public void onPause() {
+    public void onStop() {
         // Run the default commands.
-        super.onPause();
+        super.onStop();
 
         for (int i = 0; i < webViewPagerAdapter.getCount(); i++) {
             // Get the WebView tab fragment.
@@ -724,8 +738,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
         // Pause the ad or it will continue to consume resources in the background on the free flavor.
         if (BuildConfig.FLAVOR.contentEquals("free")) {
+            // Get a handle for the ad view.  This cannot be a class variable because it changes with each ad load.
+            View adView = findViewById(R.id.adview);
+
             // Pause the ad.
-            AdHelper.pauseAd(findViewById(R.id.adview));
+            AdHelper.pauseAd(adView);
         }
     }
 
@@ -807,9 +824,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         // Store a handle for the options menu so it can be used by `onOptionsItemSelected()` and `updatePrivacyIcons()`.
         optionsMenu = menu;
 
-        // Set the initial status of the privacy icons.  `false` does not call `invalidateOptionsMenu` as the last step.
-        updatePrivacyIcons(false);
-
         // Get handles for the class menu items.
         optionsPrivacyMenuItem = menu.findItem(R.id.javascript);
         optionsRefreshMenuItem = menu.findItem(R.id.refresh);
@@ -859,6 +873,9 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         MenuItem bookmarksMenuItem = menu.findItem(R.id.bookmarks);
         MenuItem adConsentMenuItem = menu.findItem(R.id.ad_consent);
 
+        // Set the initial status of the privacy icons.  `false` does not call `invalidateOptionsMenu` as the last step.
+        updatePrivacyIcons(false);
+
         // Only display third-party cookies if API >= 21
         optionsThirdPartyCookiesMenuItem.setVisible(Build.VERSION.SDK_INT >= 21);
 
@@ -1648,13 +1665,10 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             // Toggle the stored status of swipe to refresh.
             currentWebView.setSwipeToRefresh(!currentWebView.getSwipeToRefresh());
 
-            // Get a handle for the swipe refresh layout.
-            SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
-
             // Update the swipe refresh layout.
             if (currentWebView.getSwipeToRefresh()) {  // Swipe to refresh is enabled.
                 // Only enable the swipe refresh layout if the WebView is scrolled to the top.  It is updated every time the scroll changes.
-                swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
+                swipeRefreshLayout.setEnabled(currentWebView.getScrollY() == 0);
             } else {  // Swipe to refresh is disabled.
                 // Disable the swipe refresh layout.
                 swipeRefreshLayout.setEnabled(false);
@@ -2139,8 +2153,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
         // Reload the ad for the free flavor if not in full screen mode.
         if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) {
+            // Get a handle for the ad view.  This cannot be a class variable because it changes with each ad load.
+            View adView = findViewById(R.id.adview);
+
             // Reload the ad.  The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
-            AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
+            // `getContext()` can be used instead of `getActivity.getApplicationContext()` once the minimum API >= 23.
+            AdHelper.loadAd(adView, getApplicationContext(), this, getString(R.string.ad_unit_id));
         }
 
         // `invalidateOptionsMenu` should recalculate the number of action buttons from the menu to display on the app bar, but it doesn't because of the this bug:
@@ -2580,7 +2598,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     @Override
-    public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId, Bitmap favoriteIconBitmap) {
+    public void onSaveBookmarkFolder(DialogFragment dialogFragment, int selectedFolderDatabaseId, @NonNull Bitmap favoriteIconBitmap) {
         // Remove the incorrect lint warning below that the dialog fragment might be null.
         assert dialogFragment != null;
 
@@ -2681,11 +2699,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             // close the bookmarks drawer.
             drawerLayout.closeDrawer(GravityCompat.END);
         } else if (displayingFullScreenVideo) {  // A full screen video is shown.
-            // Get a handle for the layouts.
-            FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
-            RelativeLayout mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout);
-            FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
-
             // Re-enable the screen timeout.
             fullScreenVideoFrameLayout.setKeepScreenOn(false);
 
@@ -2708,7 +2721,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             if (fullScreenBrowsingModeEnabled && inFullScreenBrowsingMode) {  // Privacy Browser is currently in full screen browsing mode.
                 // Hide the banner ad in the free flavor.
                 if (BuildConfig.FLAVOR.contentEquals("free")) {
-                    AdHelper.hideAd(findViewById(R.id.adview));
+                    // Get a handle for the ad view.  This cannot be a class variable because it changes with each ad load.
+                    View adView = findViewById(R.id.adview);
+
+                    // Hide the banner ad.
+                    AdHelper.hideAd(adView);
                 }
 
                 /* Hide the system bars.
@@ -2732,8 +2749,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
             // Reload the ad for the free flavor if not in full screen mode.
             if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) {
-                // Reload the ad.
-                AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
+                // Get a handle for the ad view.  This cannot be a class variable because it changes with each ad load.
+                View adView = findViewById(R.id.adview);
+
+                // Reload the ad.  `getContext()` can be used instead of `getActivity.getApplicationContext()` once the minimum API >= 23.
+                AdHelper.loadAd(adView, getApplicationContext(), this, getString(R.string.ad_unit_id));
             }
         } else if (currentWebView.canGoBack()) {  // There is at least one item in the current WebView history.
             // Get the current web back forward list.
@@ -2856,9 +2876,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     private void loadUrlFromTextBox() {
-        // Get a handle for the URL edit text.
-        EditText urlEditText = findViewById(R.id.url_edittext);
-
         // Get the text from urlTextBox and convert it to a string.  trim() removes white spaces from the beginning and end of the string.
         String unformattedUrlString = urlEditText.getText().toString().trim();
 
@@ -3061,7 +3078,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         assert dialog != null;
 
         // Get a handle for the edit texts.
-        EditText urlEditText = dialog.findViewById(R.id.url_edittext);
+        EditText dialogUrlEditText = dialog.findViewById(R.id.url_edittext);
         EditText fileNameEditText = dialog.findViewById(R.id.file_name_edittext);
 
         // Store the URL.
@@ -3070,7 +3087,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             saveWebpageUrl = originalUrlString;
         } else {
             // Get the URL from the edit text, which may have been modified.
-            saveWebpageUrl = urlEditText.getText().toString();
+            saveWebpageUrl = dialogUrlEditText.getText().toString();
         }
 
         // Get the file path from the edit text.
@@ -3233,9 +3250,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             redColorSpan = new ForegroundColorSpan(getResources().getColor(R.color.red_900));
         }
 
-        // Get handles for the URL views.
-        EditText urlEditText = findViewById(R.id.url_edittext);
-
         // Remove the formatting from the URL edit text when the user is editing the text.
         urlEditText.setOnFocusChangeListener((View v, boolean hasFocus) -> {
             if (hasFocus) {  // The user is editing the URL text box.
@@ -3654,16 +3668,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             searchURL = searchString;
         }
 
-        // Get a handle for the app compat delegate.
-        AppCompatDelegate appCompatDelegate = getDelegate();
-
-        // Get handles for the views that need to be modified.
-        FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
-        ActionBar actionBar = appCompatDelegate.getSupportActionBar();
-
-        // Remove the incorrect lint warning below that the action bar might be null.
-        assert actionBar != null;
-
         // Apply the proxy.
         applyProxy(false);
 
@@ -3741,7 +3745,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
             // Hide the banner ad in the free flavor.
             if (BuildConfig.FLAVOR.contentEquals("free")) {
-                AdHelper.hideAd(findViewById(R.id.adview));
+                // Get a handle for the ad view.  This cannot be a class variable because it changes with each ad load.
+                View adView = findViewById(R.id.adview);
+
+                // Hide the banner ad.
+                AdHelper.hideAd(adView);
             }
 
             /* Hide the system bars.
@@ -3764,8 +3772,12 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
             // Show the banner ad in the free flavor.
             if (BuildConfig.FLAVOR.contentEquals("free")) {
+                // Get a handle for the ad view.  This cannot be a class variable because it changes with each ad load.
+                View adView = findViewById(R.id.adview);
+
                 // Initialize the ads.  If this isn't the first run, `loadAd()` will be automatically called instead.
-                AdHelper.initializeAds(findViewById(R.id.adview), getApplicationContext(), getSupportFragmentManager(), getString(R.string.google_app_id), getString(R.string.ad_unit_id));
+                // `getContext()` can be used instead of `getActivity.getApplicationContext()` once the minimum API >= 23.
+                AdHelper.initializeAds(adView, getApplicationContext(), this, getSupportFragmentManager(), getString(R.string.ad_unit_id));
             }
 
             // Remove the `SYSTEM_UI` flags from the root frame layout.
@@ -3928,10 +3940,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             // Get a handle for the cookie manager.
             CookieManager cookieManager = CookieManager.getInstance();
 
-            // Get handles for the views.
-            RelativeLayout urlRelativeLayout = findViewById(R.id.url_relativelayout);
-            SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
-
             // Initialize the user agent array adapter and string array.
             ArrayAdapter<CharSequence> userAgentNamesArray = ArrayAdapter.createFromResource(this, R.array.user_agent_names, R.layout.spinner_item);
             String[] userAgentDataArray = getResources().getStringArray(R.array.user_agent_data);
@@ -4095,7 +4103,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                         // Update the swipe refresh layout.
                         if (defaultSwipeToRefresh) {  // Swipe to refresh is enabled.
                             // Only enable the swipe refresh layout if the WebView is scrolled to the top.  It is updated every time the scroll changes.
-                            swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
+                            swipeRefreshLayout.setEnabled(currentWebView.getScrollY() == 0);
                         } else {  // Swipe to refresh is disabled.
                             // Disable the swipe refresh layout.
                             swipeRefreshLayout.setEnabled(false);
@@ -4107,7 +4115,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                         nestedScrollWebView.setSwipeToRefresh(true);
 
                         // Only enable the swipe refresh layout if the WebView is scrolled to the top.  It is updated every time the scroll changes.
-                        swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
+                        swipeRefreshLayout.setEnabled(currentWebView.getScrollY() == 0);
                         break;
 
                     case DomainsDatabaseHelper.DISABLED:
@@ -4234,7 +4242,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 // Update the swipe refresh layout.
                 if (defaultSwipeToRefresh) {  // Swipe to refresh is enabled.
                     // Only enable the swipe refresh layout if the WebView is scrolled to the top.  It is updated every time the scroll changes.
-                    swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
+                    swipeRefreshLayout.setEnabled(currentWebView.getScrollY() == 0);
                 } else {  // Swipe to refresh is disabled.
                     // Disable the swipe refresh layout.
                     swipeRefreshLayout.setEnabled(false);
@@ -4303,7 +4311,7 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 // Set the loading of webpage images.
                 nestedScrollWebView.getSettings().setLoadsImagesAutomatically(displayWebpageImages);
 
-                // Set a transparent background on URL edit text.
+                // Set a transparent background on the URL relative layout.
                 urlRelativeLayout.setBackground(ResourcesCompat.getDrawable(getResources(), R.color.transparent, null));
             }
 
@@ -4503,9 +4511,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     private void highlightUrlText() {
-        // Get a handle for the URL edit text.
-        EditText urlEditText = findViewById(R.id.url_edittext);
-
         // Only highlight the URL text if the box is not currently selected.
         if (!urlEditText.hasFocus()) {
             // Get the URL string.
@@ -4849,16 +4854,14 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     private void closeCurrentTab() {
-        // Pause the current WebView.  This prevents buffered audio from playing after the tab is closed.
-        currentWebView.onPause();
-
         // Get the current tab number.
         int currentTabNumber = tabLayout.getSelectedTabPosition();
 
         // Delete the current tab.
         tabLayout.removeTabAt(currentTabNumber);
 
-        // Delete the current page.  If the selected page number did not change during the delete, it will return true, meaning that the current WebView must be reset.
+        // Delete the current page.  If the selected page number did not change during the delete (because the newly selected tab has has same number as the previously deleted tab), it will return true,
+        // meaning that the current WebView must be reset.  Otherwise it will happen automatically as the selected tab number changes.
         if (webViewPagerAdapter.deletePage(currentTabNumber, webViewPager)) {
             setCurrentWebView(currentTabNumber);
         }
@@ -5017,13 +5020,13 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
                 // Get the WebView tab fragment.
                 WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(i);
 
-                // Get the fragment view.
-                View fragmentView = webViewTabFragment.getView();
+                // Get the WebView fragment view.
+                View webViewFragmentView = webViewTabFragment.getView();
 
                 // Only clear the cache if the WebView exists.
-                if (fragmentView != null) {
+                if (webViewFragmentView != null) {
                     // Get the nested scroll WebView from the tab fragment.
-                    NestedScrollWebView nestedScrollWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
+                    NestedScrollWebView nestedScrollWebView = webViewFragmentView.findViewById(R.id.nestedscroll_webview);
 
                     // Clear the cache for this WebView.
                     nestedScrollWebView.clearCache(true);
@@ -5113,11 +5116,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
     }
 
     private void setCurrentWebView(int pageNumber) {
-        // Get handles for the URL views.
-        RelativeLayout urlRelativeLayout = findViewById(R.id.url_relativelayout);
-        EditText urlEditText = findViewById(R.id.url_edittext);
-        SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
-
         // Stop the swipe to refresh indicator if it is running
         swipeRefreshLayout.setRefreshing(false);
 
@@ -5125,17 +5123,17 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
         WebViewTabFragment webViewTabFragment = webViewPagerAdapter.getPageFragment(pageNumber);
 
         // Get the fragment view.
-        View fragmentView = webViewTabFragment.getView();
+        View webViewFragmentView = webViewTabFragment.getView();
 
         // Set the current WebView if the fragment view is not null.
-        if (fragmentView != null) {  // The fragment has been populated.
+        if (webViewFragmentView != null) {  // The fragment has been populated.
             // Store the current WebView.
-            currentWebView = fragmentView.findViewById(R.id.nestedscroll_webview);
+            currentWebView = webViewFragmentView.findViewById(R.id.nestedscroll_webview);
 
             // Update the status of swipe to refresh.
             if (currentWebView.getSwipeToRefresh()) {  // Swipe to refresh is enabled.
                 // Enable the swipe refresh layout if the WebView is scrolled all the way to the top.  It is updated every time the scroll changes.
-                swipeRefreshLayout.setEnabled(currentWebView.getY() == 0);
+                swipeRefreshLayout.setEnabled(currentWebView.getScrollY() == 0);
             } else {  // Swipe to refresh is disabled.
                 // Disable the swipe refresh layout.
                 swipeRefreshLayout.setEnabled(false);
@@ -5260,20 +5258,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             }
         }
 
-        // Get a handle for the app compat delegate.
-        AppCompatDelegate appCompatDelegate = getDelegate();
-
-        // Get handles for the activity views.
-        FrameLayout rootFrameLayout = findViewById(R.id.root_framelayout);
-        RelativeLayout mainContentRelativeLayout = findViewById(R.id.main_content_relativelayout);
-        ActionBar actionBar = appCompatDelegate.getSupportActionBar();
-        LinearLayout tabsLinearLayout = findViewById(R.id.tabs_linearlayout);
-        EditText urlEditText = findViewById(R.id.url_edittext);
-        SwipeRefreshLayout swipeRefreshLayout = findViewById(R.id.swiperefreshlayout);
-
-        // Remove the incorrect lint warning below that the action bar might be null.
-        assert actionBar != null;
-
         // Get a handle for the activity
         Activity activity = this;
 
@@ -5349,7 +5333,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
                         // Hide the banner ad in the free flavor.
                         if (BuildConfig.FLAVOR.contentEquals("free")) {
-                            AdHelper.hideAd(findViewById(R.id.adview));
+                            // Get a handle for the ad view.  This cannot be a class variable because it changes with each ad load.
+                            View adView = findViewById(R.id.adview);
+
+                            // Hide the banner ad.
+                            AdHelper.hideAd(adView);
                         }
 
                         /* Hide the system bars.
@@ -5387,8 +5375,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
                         // Show the banner ad in the free flavor.
                         if (BuildConfig.FLAVOR.contentEquals("free")) {
-                            // Reload the ad.
-                            AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
+                            // Get a handle for the ad view.  This cannot be a class variable because it changes with each ad load.
+                            View adView = findViewById(R.id.adview);
+
+                            // Reload the ad.  `getContext()` can be used instead of `getActivity.getApplicationContext()` once the minimum API >= 23.
+                            AdHelper.loadAd(adView, getApplicationContext(), activity, getString(R.string.ad_unit_id));
                         }
 
                         // Remove the `SYSTEM_UI` flags from the root frame layout.
@@ -5603,16 +5594,16 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             // Enter full screen video.
             @Override
             public void onShowCustomView(View video, CustomViewCallback callback) {
-                // Get a handle for the full screen video frame layout.
-                FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
-
                 // Set the full screen video flag.
                 displayingFullScreenVideo = true;
 
                 // Pause the ad if this is the free flavor.
                 if (BuildConfig.FLAVOR.contentEquals("free")) {
+                    // Get a handle for the ad view.  This cannot be a class variable because it changes with each ad load.
+                    View adView = findViewById(R.id.adview);
+
                     // The AdView is destroyed and recreated, which changes the ID, every time it is reloaded to handle possible rotations.
-                    AdHelper.pauseAd(findViewById(R.id.adview));
+                    AdHelper.pauseAd(adView);
                 }
 
                 // Hide the keyboard.
@@ -5646,9 +5637,6 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
             // Exit full screen video.
             @Override
             public void onHideCustomView() {
-                // Get a handle for the full screen video frame layout.
-                FrameLayout fullScreenVideoFrameLayout = findViewById(R.id.full_screen_video_framelayout);
-
                 // Re-enable the screen timeout.
                 fullScreenVideoFrameLayout.setKeepScreenOn(false);
 
@@ -5680,7 +5668,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
                     // Hide the banner ad in the free flavor.
                     if (BuildConfig.FLAVOR.contentEquals("free")) {
-                        AdHelper.hideAd(findViewById(R.id.adview));
+                        // Get a handle for the ad view.  This cannot be a class variable because it changes with each ad load.
+                        View adView = findViewById(R.id.adview);
+
+                        // Hide the banner ad.
+                        AdHelper.hideAd(adView);
                     }
 
                     /* Hide the system bars.
@@ -5698,8 +5690,11 @@ public class MainWebViewActivity extends AppCompatActivity implements CreateBook
 
                 // Reload the ad for the free flavor if not in full screen mode.
                 if (BuildConfig.FLAVOR.contentEquals("free") && !inFullScreenBrowsingMode) {
-                    // Reload the ad.
-                    AdHelper.loadAd(findViewById(R.id.adview), getApplicationContext(), getString(R.string.ad_unit_id));
+                    // Get a handle for the ad view.  This cannot be a class variable because it changes with each ad load.
+                    View adView = findViewById(R.id.adview);
+
+                    // Reload the ad.  `getContext()` can be used instead of `getActivity.getApplicationContext()` once the minimum API >= 23.
+                    AdHelper.loadAd(adView, getApplicationContext(), activity, getString(R.string.ad_unit_id));
                 }
             }