首页 > 解决方案 > 尝试在 libgdx Admob 实现中调用空对象引用上的接口方法

问题描述

我正在 libgdx 游戏中实现 admob 横幅广告。我制作了几个屏幕,并希望在每个屏幕上都显示横幅广告。我在启动器类中实现了横幅广告,并试图通过接口方法调用在屏幕类中显示它,但应用程序每次都因错误而崩溃。

4-22 20:47:14.466 24246-24280/com.mygdx.game E/AndroidRuntime:致命异常:GLThread 80476

Process: com.mygdx.game, PID: 24246
java.lang.NullPointerException: Attempt to invoke interface method 'void com.mygdx.game.AdsController.showBannerAd()' on a null object reference
    at com.mygdx.game.BabyOrange.create(BabyOrange.java:51)
    at com.mygdx.game.BabyScreen.<init>(BabyScreen.java:38)
    at com.mygdx.game.BabyOrange.<init>(BabyOrange.java:42)
    at com.mygdx.game.BabyGame.create(BabyGame.java:9)
    at com.badlogic.gdx.backends.android.AndroidGraphics.onSurfaceChanged(AndroidGraphics.java:311)
    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1633)
    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1354)

这是启动器和屏幕类的代码

public class BabyOrange extends BabyScreen {

private BabyActor bg;
private BabyActor ph;

private AdsController adsController;

public BabyOrange(Game g,AdsController adsController){
   super(g);
   this.adsController = adsController;


}

 public void create () {
   adsController.showBannerAd();

    bg = new BabyActor();
    bg.setTexture(asset.get("background-orange.png",Texture.class));
    bg.setSize(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());

    ph = new BabyActor();
    ph.setTexture(asset.get("orange-ph.png",Texture.class));
    ph.setSize(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());

 }

这是界面

public interface AdsController {
public void showBannerAd();
public void hideBannerAd();
 }

和 Android 启动器类

public class AndroidLauncher extends AndroidApplication implements AdsController{

private static final String BANNER_ID = "ca-app-pub-959117648XXXXXX/XXXXXXXX";
AdView bannerAd;
@Override
protected void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();

    //create a gameView and a bannerAd AdView
    View gameView = initializeForView(new BabyGame(), config);

    setupAds();

    //define the layout
    RelativeLayout layout = new RelativeLayout(this);
    layout.addView(gameView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

    RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT);
    params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
    layout.addView(bannerAd,params);
    setContentView(layout);
}

public void setupAds(){
    bannerAd = new AdView(this);
    bannerAd.setVisibility(View.INVISIBLE);
    bannerAd.setAdUnitId(BANNER_ID);
    bannerAd.setAdSize(AdSize.SMART_BANNER);
}

@Override
public void showBannerAd() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            bannerAd.setVisibility(View.VISIBLE);
            AdRequest.Builder builder = new AdRequest.Builder();
            AdRequest ad = builder.build();
            bannerAd.loadAd(ad);
        }
    });
}

@Override
public void hideBannerAd() {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            bannerAd.setVisibility(View.INVISIBLE);
        }
    });
}

}

标签: androidlibgdxadmob

解决方案


Your super constructor calls the underlying create function before your adsController is set. Try this code:

public BabyOrange(Game g,AdsController adsController){
    super(g);
    this.adsController = adsController;
    create2();
}

public void create2() {
    adsController.showBannerAd();
}

public void create () { // called within super-constructor
    bg = new BabyActor();
    bg.setTexture(asset.get("background-orange.png",Texture.class));
    bg.setSize(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());

    ph = new BabyActor();
    ph.setTexture(asset.get("orange-ph.png",Texture.class));
    ph.setSize(Gdx.graphics.getWidth(),Gdx.graphics.getHeight());

}

...

推荐阅读