AdMob Interstitial 和错误 isLoaded 必须在主 UI 线程上调用
AdMob Interstitial and error isLoaded must be called on the main UI thread
在用户 William 建议我更改显示插页式广告的代码后
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//setDebugMode(true);
initialiseAccelerometer();
interstitial = new InterstitialAd(this);
interstitial.setAdUnitId(getResources().getString(R.string.InterstitialAd_unit_id));
interstitial.setAdListener(new AdListener() {
public void onAdClosed() {
// Create another ad request.
final AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
interstitial.loadAd(adRequest);
}
});
// Create ad request.
final AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
interstitial.loadAd(adRequest);
}
为了展示这个广告:
public synchronized void GameOver() {
if (lives_left > 0) {
//success! - game passed - save score
ScoreManager.save_localscore_simple(score_times[currentLevel], "" + currentLevel, false);
if (Level_Buttons.length >= currentLevel + 1)
ScoreManager.save_localscore_simple(unlocked, "unlock" + (currentLevel + 1));
if (sound_success != 0 && !sound_muted)
sp.play(sound_success, 1, 1, 0, 0, 1);
//open interstitial ad
if (interstitial.isLoaded()) {
interstitial.show();
}
} else {
//game not passed
if (sound_gameover != 0 && !sound_muted)
sp.play(sound_gameover, 1, 1, 0, 0, 1);
}
//open interstitial ad
if (interstitial.isLoaded()) {
interstitial.show();
}
StopMusic();
state = GAMEOVER;
}
在游戏的每次游戏结束时,我都会收到此错误:
W/dalvikvm(20469): threadid=11: thread exiting with uncaught exception (group=0x4180bda0)
E/AndroidRuntime(20469): FATAL EXCEPTION: Thread-67543
E/AndroidRuntime(20469): Process: com.test.mygame, PID: 20469
E/AndroidRuntime(20469): java.lang.IllegalStateException: isLoaded must be called on the main UI thread.
E/AndroidRuntime(20469): at com.google.android.gms.common.internal.bh.b(SourceFile:251)
E/AndroidRuntime(20469): at com.google.android.gms.ads.internal.b.e(SourceFile:345)
E/AndroidRuntime(20469): at com.google.android.gms.ads.internal.client.m.onTransact(SourceFile:66)
E/AndroidRuntime(20469): at android.os.Binder.transact(Binder.java:361)
E/AndroidRuntime(20469): at com.google.android.gms.internal.ap$a$a.isReady(Unknown Source)
E/AndroidRuntime(20469): at com.google.android.gms.internal.au.isLoaded(Unknown Source)
E/AndroidRuntime(20469): at com.google.android.gms.ads.InterstitialAd.isLoaded(Unknown Source)
E/AndroidRuntime(20469): at com.test.mygame.MainGame.GameOver(MainGame.java:1128)
E/AndroidRuntime(20469): at com.test.mygame.MainGame.Step(MainGame.java:773)
E/AndroidRuntime(20469): at com.test.nudge.Screen.run(Screen.java:207)
E/AndroidRuntime(20469): at java.lang.Thread.run(Thread.java:841)
这里有什么问题?请尽可能简单地解释我,因为我是新手,之前没有任何编程知识:) 谢谢!
这可能不是完整的答案,但很难说出正确的答案,因为从上面的代码中看不清楚。你没有显示你在哪里使用 GameOver(),但我认为你在错误的地方调用它,我认为你在任何后台线程中调用它,因为在 GameOver 中你调用 interstitial.isLoaded()
导致你的问题。就像堆栈跟踪所说的那样,在主 ui 线程中调用它。例如,在你的 GameOver() 中调用它:
runOnUiThread(new Runnable() {
@Override public void run() {
if (interstitial.isLoaded()) {
interstitial.show();
}
}
});
可能您必须使用 activity 引用来调用它,这取决于您从何处调用 GameOver():
mYourActivity.runOnUiThread(new Runnable() {
@Override public void run() {
if (interstitial.isLoaded()) {
interstitial.show();
}
}
});
分享我的案例和解决方案。
我创建了新线程并调用了 isLoaded()。它得到了同样的错误。
所以我使用 Messager 通过下面的代码解决了它。
希望对您有所帮助。
代码如下。
主线程:
public void onCreate() {
mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case ACTION_ADMOB_IS_LOADED:
MainActivity.logForDebug(TAG,"AdMob : Check for loaded");
if(mIAds.isLoaded()) {
MainActivity.logForDebug(TAG,"AdMob : Loaded ...... OK");
mIAds.show();
}
break;
}
}
};
}
其他线程
public void run(){
while(true){
Message message;
// ------ For AdMob ------
Message message = mHandler.obtainMessage(ACTION_ADMOB_IS_LOADED,null);
message.sendToTarget();
}
}
在用户 William 建议我更改显示插页式广告的代码后
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
//setDebugMode(true);
initialiseAccelerometer();
interstitial = new InterstitialAd(this);
interstitial.setAdUnitId(getResources().getString(R.string.InterstitialAd_unit_id));
interstitial.setAdListener(new AdListener() {
public void onAdClosed() {
// Create another ad request.
final AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
interstitial.loadAd(adRequest);
}
});
// Create ad request.
final AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.build();
interstitial.loadAd(adRequest);
}
为了展示这个广告:
public synchronized void GameOver() {
if (lives_left > 0) {
//success! - game passed - save score
ScoreManager.save_localscore_simple(score_times[currentLevel], "" + currentLevel, false);
if (Level_Buttons.length >= currentLevel + 1)
ScoreManager.save_localscore_simple(unlocked, "unlock" + (currentLevel + 1));
if (sound_success != 0 && !sound_muted)
sp.play(sound_success, 1, 1, 0, 0, 1);
//open interstitial ad
if (interstitial.isLoaded()) {
interstitial.show();
}
} else {
//game not passed
if (sound_gameover != 0 && !sound_muted)
sp.play(sound_gameover, 1, 1, 0, 0, 1);
}
//open interstitial ad
if (interstitial.isLoaded()) {
interstitial.show();
}
StopMusic();
state = GAMEOVER;
}
在游戏的每次游戏结束时,我都会收到此错误:
W/dalvikvm(20469): threadid=11: thread exiting with uncaught exception (group=0x4180bda0)
E/AndroidRuntime(20469): FATAL EXCEPTION: Thread-67543
E/AndroidRuntime(20469): Process: com.test.mygame, PID: 20469
E/AndroidRuntime(20469): java.lang.IllegalStateException: isLoaded must be called on the main UI thread.
E/AndroidRuntime(20469): at com.google.android.gms.common.internal.bh.b(SourceFile:251)
E/AndroidRuntime(20469): at com.google.android.gms.ads.internal.b.e(SourceFile:345)
E/AndroidRuntime(20469): at com.google.android.gms.ads.internal.client.m.onTransact(SourceFile:66)
E/AndroidRuntime(20469): at android.os.Binder.transact(Binder.java:361)
E/AndroidRuntime(20469): at com.google.android.gms.internal.ap$a$a.isReady(Unknown Source)
E/AndroidRuntime(20469): at com.google.android.gms.internal.au.isLoaded(Unknown Source)
E/AndroidRuntime(20469): at com.google.android.gms.ads.InterstitialAd.isLoaded(Unknown Source)
E/AndroidRuntime(20469): at com.test.mygame.MainGame.GameOver(MainGame.java:1128)
E/AndroidRuntime(20469): at com.test.mygame.MainGame.Step(MainGame.java:773)
E/AndroidRuntime(20469): at com.test.nudge.Screen.run(Screen.java:207)
E/AndroidRuntime(20469): at java.lang.Thread.run(Thread.java:841)
这里有什么问题?请尽可能简单地解释我,因为我是新手,之前没有任何编程知识:) 谢谢!
这可能不是完整的答案,但很难说出正确的答案,因为从上面的代码中看不清楚。你没有显示你在哪里使用 GameOver(),但我认为你在错误的地方调用它,我认为你在任何后台线程中调用它,因为在 GameOver 中你调用 interstitial.isLoaded()
导致你的问题。就像堆栈跟踪所说的那样,在主 ui 线程中调用它。例如,在你的 GameOver() 中调用它:
runOnUiThread(new Runnable() {
@Override public void run() {
if (interstitial.isLoaded()) {
interstitial.show();
}
}
});
可能您必须使用 activity 引用来调用它,这取决于您从何处调用 GameOver():
mYourActivity.runOnUiThread(new Runnable() {
@Override public void run() {
if (interstitial.isLoaded()) {
interstitial.show();
}
}
});
分享我的案例和解决方案。
我创建了新线程并调用了 isLoaded()。它得到了同样的错误。 所以我使用 Messager 通过下面的代码解决了它。
希望对您有所帮助。
代码如下。
主线程:
public void onCreate() {
mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message message) {
switch (message.what) {
case ACTION_ADMOB_IS_LOADED:
MainActivity.logForDebug(TAG,"AdMob : Check for loaded");
if(mIAds.isLoaded()) {
MainActivity.logForDebug(TAG,"AdMob : Loaded ...... OK");
mIAds.show();
}
break;
}
}
};
}
其他线程
public void run(){
while(true){
Message message;
// ------ For AdMob ------
Message message = mHandler.obtainMessage(ACTION_ADMOB_IS_LOADED,null);
message.sendToTarget();
}
}