【问题标题】:Admob Interstitial Singleton Pattern java.lang.NullPointerException:Admob 插页式单例模式 java.lang.NullPointerException:
【发布时间】:2019-10-04 21:30:18
【问题描述】:

我正在使用 Singleton 模式来展示 Admob 插页式广告。其实模拟器没问题。我试过不同的智能手机没问题。一切正常。但是当涉及到 Google Play 开发者控制台时,我遇到了这些错误。

java.lang.RuntimeException: 
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2200)
  at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2250)
  at android.app.ActivityThread.access$800 (ActivityThread.java:139)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1200)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loop (Looper.java:136)
  at android.app.ActivityThread.main (ActivityThread.java:5105)
  at java.lang.reflect.Method.invokeNative (Native Method)
  at java.lang.reflect.Method.invoke (Method.java:515)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:792)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:608)
  at dalvik.system.NativeStart.main (Native Method)
Caused by: java.lang.NullPointerException: 
  at x.y.z.ViewItemActivity.onCreate (ViewItemActivity.java:48)
  at android.app.Activity.performCreate (Activity.java:5275)
  at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1087)
  at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2164)

引起:java.lang.NullPointerException: 在 x.y.z.ViewItemActivity.onCreate (ViewItemActivity.java:48)

ViewItemActivity 中的第 48 行:

if (ad.isLoaded()) {//Line 48
            ad.show();
        }

让我展示一下,AdManager 类和用法

AdManager 类:

package x;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.util.Log;

import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.InterstitialAd;

import x.y.z.R;
import x.y.z.app.App;

public class AdManager {


    static InterstitialAd ad;
    private Context ctx;

    public AdManager(Context ctx) {
        this.ctx = ctx;
    }

    public void createAd() {
        // Create an ad.
        ad = new InterstitialAd(ctx);
        ad.setAdUnitId(App.getResourses().getString(R.string.interstitial_ad_unit));

        final AdRequest adRequest = new AdRequest.Builder().build();

        // Load the interstitial ad.
        ad.loadAd(adRequest);

       // Log.d("admobshowing","asdf");
    }

    public InterstitialAd getAd() {
        return ad;
    }
}

我在 OnCreate 的 MainActivity 中请求:

AdManager adManager = new AdManager(MainActivity.this);
adManager.createAd();

我在另一个活动中显示它 - ViewItemActivity - 在 setContentView 之前:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    AdManager adManager = new AdManager(ViewItemActivity.this);
    InterstitialAd ad = adManager.getAd();
    if (ad.isLoaded()) {
        ad.show();
    }

    setContentView(R.layout.activity_view_item);

....

....

当用户按下返回按钮时我再次请求:- ViewItemActivity

@Override
public void onBackPressed(){
AdManager adManager = new AdManager(ViewItemActivity.this);
adManager.createAd();
super.onBackPressed();
}

因此,当我单独尝试时,我在模拟器或真正的智能手机中没有出现错误,但在 Google Play 开发者控制台中,我得到了数十个空指针异常。我该如何解决我的问题?

【问题讨论】:

    标签: java android android-studio admob singleton


    【解决方案1】:

    我认为单例模式不适合您的用例。您正在尝试为每个上下文创建一个新广告,因此在 AdManager 的实例中保留广告没有任何好处。您可以将您的 AdManager 更改为以下内容并删除对 createAd 的所有调用。

    public class AdManager {
    
        private InterstitialAd ad;
        private Context ctx;
    
        public AdManager(Context ctx) {
            this.ctx = ctx;
        }
    
        private void createAd() {
            // Create an ad.
            ad = new InterstitialAd(ctx);
            ad.setAdUnitId(App.getResourses().getString(R.string.interstitial_ad_unit));
    
            final AdRequest adRequest = new AdRequest.Builder().build();
    
            // Load the interstitial ad.
            ad.loadAd(adRequest);
        }
    
        public InterstitialAd getAd() {
            if (ad == null) {
                createAd();
            }
            return ad;
        }
    }
    

    【讨论】:

    • 如果我可以这样做,显示率将大约为 0。首先,我想要请求,然后在几秒钟后显示。 (不是立即)
    • 为什么我的代码在我的真实智能手机和模拟器上运行良好时却不能在其他智能手机上运行?这是最重要的问题
    • 如果您想在活动的onCreate 中创建对广告的本地引用,这将满足您的问题。至于为什么它不起作用,您可能遇到了这种单例方法经常引入的竞争条件。在您调用 getAd() 后,您的代码中没有验证,这意味着您将自己暴露于 NPE,就像您所看到的那样。以上保证从getAd()返回非空广告。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 2018-01-03
    相关资源
    最近更新 更多