【问题标题】:Android WebView disappears after closing interstitial video ad关闭插页式视频广告后,Android WebView 消失
【发布时间】:2016-03-11 06:17:07
【问题描述】:

我使用this AdMob 手册向我的应用添加了插页式广告。该应用程序有一个 MainActivity 和一个 WebView 用于处理拼图的游戏,以及一个用于处理导航的顶部栏和导航抽屉。

插页式广告适用于文字和图片广告,但不适用于视频广告。关闭视频广告后,WebView 消失了(顶部栏和导航抽屉仍然存在)。如果我然后单击导航抽屉中的菜单项,该菜单项应该导航到 WebView 中的新页面,应用程序会崩溃并显示以下 NullPointerException(在 Android 4.2 和 6.0 设备上测试):

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.webkit.WebView.loadUrl(java.lang.String)' on a null object reference
    at com.bd.test.MainActivity.k(Unknown Source)
    at com.bd.test.MainActivity.a(Unknown Source)
    at android.support.design.widget.aa.a(Unknown Source)
    at android.support.v7.view.menu.i.a(Unknown Source)
    at android.support.v7.view.menu.m.b(Unknown Source)
    at android.support.v7.view.menu.i.a(Unknown Source)
    at android.support.design.internal.d.onClick(Unknown Source)
    at android.view.View.performClick(View.java:5198)
    at android.view.View$PerformClick.run(View.java:21147)
    at android.os.Handler.handleCallback(Handler.java:742)
    at android.os.Handler.dispatchMessage(Handler.java:97)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5457)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

菜单项点击处理程序调用我的WebView 对象mWebViewloadUrl 函数,该函数在显示或关闭插页式视频广告时以某种方式设置为null

两个WebView之间会不会有干扰;我的和显示插页式广告的那个(类似于我之前的横幅广告observed)?

或者我只是在我的代码中犯了一个错误?我的MainActivity的相关部分如下:

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    protected WebView mWebView;
    protected InterstitialAd mInterstitialAd;

    protected int pageId = R.id.nav_home;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //initToolbar();
        //initDrawer();
        //initNavigationView();

        initAdInterstitial();

        if (savedInstanceState != null) {
            return;
        }

        initWebView();
        navigate();
    }

    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        pageId = item.getItemId();
        navigate();
        return true;
    }

    protected void navigate() {

        // Close drawer if it is open.
        if(mDrawer.isDrawerOpen(GravityCompat.START)) {
            mDrawer.closeDrawer(GravityCompat.START);
        }

        if(pageId == R.id.nav_home) {
            mWebView.loadUrl(URL_INDEX);
        }
        else if(pageId == R.id.nav_level0) {
            mWebView.loadUrl(getLevelUrl(0));
        }
        else if(pageId == R.id.nav_level1) {
            mWebView.loadUrl(getLevelUrl(1));
        }
        else if(pageId == R.id.nav_level2) {
            mWebView.loadUrl(getLevelUrl(2));
        }
        else if(pageId == R.id.nav_level3) {
            mWebView.loadUrl(getLevelUrl(3));
        }
        else if(pageId == R.id.nav_history) {
            mWebView.loadUrl(URL_LAST_PLAYED);
        }
    }

    protected void initWebView() {

        mWebView = (WebView) findViewById(R.id.webview);

        // Enable Javascript
        WebSettings webSettings = mWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setDomStorageEnabled(true);
        webSettings.setDatabaseEnabled(true);
        webSettings.setAllowUniversalAccessFromFileURLs(true);
        webSettings.setDefaultTextEncodingName("utf-8");

        // Deprecated.
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
            Context c = mWebView.getContext();
            webSettings.setDatabasePath(c.getFilesDir().getPath() + c.getPackageName() +
                    "/databases/");
        }

        mWebView.setWebViewClient(new WebViewClient() {

            /*
             * HERE IS WHERE THE INTERSTITIAL AD IS SHOWN.
             *
             * Shows the interstitial ad every n-th page load.
             */
            public void onPageFinished(WebView view, String url) {

                // After WebView page is loaded:

                // Update page load count.
                navigationCount = (navigationCount + 1) % adFrequency;

                // Show ad once every n-th page load.
                if(navigationCount == 0) {
                    showAd();
                }
            }
        });
    }

    protected void initAdInterstitial() {
        mInterstitialAd = new InterstitialAd(this);
        mInterstitialAd.setAdUnitId(getString(R.string.interstitial_ad_unit_id));

        mInterstitialAd.setAdListener(new AdListener() {
            @Override
            public void onAdClosed() {
                requestNewInterstitial();
            }
        });
        requestNewInterstitial();
    }

    protected void requestNewInterstitial() {
        AdRequest adRequest = new AdRequest.Builder().build();
        mInterstitialAd.loadAd(adRequest);
    }

    public void showAd() {
        if (mInterstitialAd.isLoaded()) {
            mInterstitialAd.show();
        }
    }
}

【问题讨论】:

    标签: android admob android-webview


    【解决方案1】:

    我怀疑是因为onCreate()中的这一行

    if (savedInstanceState != null) {
                return;
            }
    

    当您返回到您的 Activity 时,您将拥有一个非空的 savedInstanceState,因此永远不会初始化您的 WebView。

    注意,如果您对堆栈跟踪进行去混淆处理或使用行号发布源代码,这会有所帮助。

    【讨论】:

    • 我知道,我试图获得一个去混淆的堆栈跟踪,但我的去混淆调试版本上从来没有视频插页式广告(只有文本和图像,然后它工作正常)。因此,我目前只有来自混淆版本的堆栈跟踪。但是我希望的解释很清楚,当在导航函数中调用 loadUrl 时,变量 mWebView 为空。
    • 您对 savedInstanceState 的看法很可能是正确的(我忽略了一点,根据一些 Fragment 文档插入了 if 语句,但后来忘记更新它)。我只能在今天晚些时候或明天测试它,我会在之后回复答案。
    • 你确实是对的。视频广告花了很长时间才出现,但它终于出现了,而且奏效了!谢谢威廉!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    相关资源
    最近更新 更多