android - 尝试在 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);
}
});
}
}
解决方案
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());
}
...
推荐阅读
- reactjs - 为什么我不能在 4 行网格的最后一个框中输入
- laravel - 在 Laravel Vapor 上管理排队作业/数据库连接/性能
- javascript - 如何从路由函数外部获取 Nodejs 响应对象?
- c++ - C++ std::string 语法“new (&y) std::string(x);”
- c - 什么是“命名空间清洁度”,glibc 是如何实现的?
- c# - 如何保存 XML 文件而不在空的打开和关闭标签之间添加换行符?
- javascript - 循环检查条件的Javascript
- python - Python:如果存在,则在子字符串之前有 4 个单词
- c++ - 为什么我的替代排序算法不起作用?
- vba - 为 PowerPoint (Office 365) Mac 开发自定义功能区加载项