cocos2d-xのAdmob表示のバグ
AndroidアプリにAdmobの広告を表示しようとして、謎のバグにハマったのでメモ
Admobが表示されず、cocos2d-xを終了しようとするとアプリがフリーズするという症状です。
ネットで調べても同じようなバグ報告が見つからなかったので、機種等の環境に依存するのかもです。
なかなか解決できなくて大分時間がかかっちゃいました('A';;
OSは2.3.5、4.0.3の両方で確認。
通信ON/OFF関係無く発生します。
再現性としては2.3.5のほうは10%ぐらい、 4.0.3のほうが20%ぐらい。なんででしょうね?
Admobの表示
まず、Admobの基本的な表示方法
// OnCreate /////////////////////////////// // adView を作成する adView = new AdView(this, AdSize.BANNER, MY_AD_UNIT_ID); // 属性 android:id="@+id/mainLayout" が与えられているものとして // LinearLayout をルックアップする LinearLayout layout = (LinearLayout)findViewById(R.id.mainLayout); // adView を追加 layout.addView(adView); // 一般的なリクエストを行って広告を読み込む adView.loadAd(new AdRequest());
logcatは次のようになっています。
DexOpt: --- BEGIN 'ads-XXXXXXXXXX.jar' (bootstrap=0) ---
DexOpt: --- END 'ads-XXXXXXXXXX.jar' (success) ---
adRequestUrlHtml:
Received ad url:
loadADの後、ads.jarを読み込み開始 → 終了 → urlリクエストを投げる → url受け取り
みたいな流れだと思います。
バグが発生時ですが、DexOptが失敗しBEGINの後にENDが送られて来ません。
スレッドを見てみると、失敗時はスレッド1個が終了出来ていないのが見れます。
このスレッドがcocos2d-x終了後も残ってしまうので、アプリが正常に終了出来ずフリーズしてしまいます。
AdView.stoploadingでも止まらず、再びloadAdしても「読み込み中です」エラーが返るだけ。
jarの読み込みで停止してしまうので、リクエストエラーも返ってこない、例外も投げられないという
非常に分かりにくい!
解決方法
いろいろ試した結果、自分なりの解決方法
AdViewの作成と、リクエストの送信を分けるだけです。
// OnCreate /////////////////////////////// // adView を作成する adView = new AdView(this, AdSize.BANNER, MY_AD_UNIT_ID); // 属性 android:id="@+id/mainLayout" が与えられているものとして // LinearLayout をルックアップする LinearLayout layout = (LinearLayout)findViewById(R.id.mainLayout); // adView を追加 layout.addView(adView);
その後、処理が軽い所でリクエストを投げます。
me.runOnUiThread( new Runnable(){ public void run(){ // 一般的なリクエストを行って広告を読み込む adView.loadAd(new AdRequest()); } });
ただこれだけです。
どうもadView後loadAdをすぐに投げると失敗するようです。
なのでAdViewの作成と、リクエストの送信分けました。
同じ症状ではないですが、処理が重い時にリクエストを投げると、うまく表示されないという
情報があったので、リクエストはロードなどの処理の後に投げるようにしました。
これが正解かどうかは分かりませんが、今のところバグは発生していません。
機種依存だったり、通信関係のバグは情報も少なくて困っちゃいますね。