cocos2d-xでAndroid側でGLSafirceViewをonPauseするとエラーる
やりたいこと
Androidでcocos2d-xを表示しているActivity上でIn-app Billing v3のActivityDialogを上に表示したかった。
エラー内容
課金のDialogActivityが上に表示されるとonPause()が実行されてCCApplication.cppで以下のエラーが発生した。
E/cocos2d-x assert(4410): /Applications/cocos2d-x-2.1.4/projects/HelloWorldProjct/proj.android/../../../cocos2dx/platform/android/CCApplication.cpp function:sharedApplication line:60
ソースを追って見てみるとassertで落とされてる様子。 つまり、実装方法が悪いっぽい。
CCApplication.cpp
CCApplication* CCApplication::sharedApplication() { CCAssert(sm_pSharedApplication, ""); return sm_pSharedApplication; }
どこからシングルトンのCCApplicationを呼んで落ちているのか? ひたすらログを貼っつけて調査した結果。
Cocos2dxActivity.java
@Override protected void onPause() { super.onPause(); Cocos2dxHelper.onPause(); this.mGLSurfaceView.onPause(); // ★ここ }
Cocos2dxGLSurfaceView.java
@Override public void onPause() { this.queueEvent(new Runnable() { @Override public void run() { Cocos2dxGLSurfaceView.this.mCocos2dxRenderer.handleOnPause(); // ★ここ } }); //super.onPause(); }
Cocos2dxRenderer.java
public void handleOnPause() { Cocos2dxRenderer.nativeOnPause(); // ★ここ }
Java_org_cocos2dx_lib_Cocos2dxRenderer.cpp
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnPause() { CCApplication::sharedApplication()->applicationDidEnterBackground(); // ★ここやね CCNotificationCenter::sharedNotificationCenter()->postNotification(EVENT_COME_TO_BACKGROUND, NULL); }
JNIで呼ばれたタイミングですでにCCApplicationが死んでいる?というのはどうも考えにくい。。。 というわけで、上記にログを仕込んでみる。
Java_org_cocos2dx_lib_Cocos2dxRenderer.cpp
JNIEXPORT void JNICALL Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeOnPause() { CCLog("CCApplication = %s", sm_pSharedApplication); // ★追加 CCApplication::sharedApplication()->applicationDidEnterBackground(); CCNotificationCenter::sharedNotificationCenter()->postNotification(EVENT_COME_TO_BACKGROUND, NULL); }
実行してみる
08-29 11:28:40.484: D/HelloWorldProjct(5030): Upgrade button clicked; launching purchase flow for upgrade. 08-29 11:28:40.488: D/IabHelper(5030): Starting async operation: launchPurchaseFlow 08-29 11:28:40.542: D/HelloWorldProjct(5030): #################### onPause 08-29 11:28:40.542: D/MyCocos2dxActivity(5030): Cocos2dxHelper.onPause() 08-29 11:28:40.542: D/cocos2d-x debug info(5030): CCApplication = (null) 08-29 11:28:40.542: E/cocos2d-x assert(5030): /Applications/cocos2d-x-2.1.4/projects/HelloWorldProjct/proj.android/../../../cocos2dx/platform/android/CCApplication.cpp function:sharedApplication line:62
見事落ちた。。。nullってます。
とまあ、ここまで追って理解。 アプリ起動時(onCreateメソッド内)にてWebViewを前面表示し、GLSurfaceViewを非表示にしていたのですが、どうやらこれが原因で、GLThread側の初期処理が終わってなかったみたいです・・・
mGLSurfaceView.setVisibility(View.GONE);
対処方法
最初に表示するSceneの表示終了時にJava側のメソッドを呼び出してそこで画面を非表示にするように修正しました。
呼び出し順のログ
08-29 14:25:22.230: D/cocos2d-x debug info(1203): ######## init 08-29 14:25:22.265: W/GLThread(1203): onSurfaceChanged(480, 800) 08-29 14:25:22.269: D/cocos2d-x debug info(1203): ######## onEnter 08-29 14:25:22.269: D/cocos2d-x debug info(1203): ######## onEnterTransitionDidFinish 08-29 14:25:22.269: D/HelloWorldProjct(1203): onInitSceneEnter! ThreadName = GLThread 12
HelloWorldScene.cpp
void HelloWorld::onEnter() { CCLayer::onEnter(); // super呼び出し CCLog("######## onEnter"); } void HelloWorld::onEnterTransitionDidFinish() { CCLayer::onEnterTransitionDidFinish(); // super呼び出し CCLog("######## onEnterTransitionDidFinish"); // Java呼び出し NativeLauncher::launchNativeInitSceneFinish(); }
見事落ちなくなりました。