AndroidNDK openGLが落ちないように。
GLSurfaceViewを持っているActivityを閉じたり、
再表示するとどうにもアプリケーションが死ぬ、落ちてしまうことが多々ありました。
ちょっと原因が分からないなぁと思いながら色々試行錯誤した結果、現在では
何とか落ちなくなっています。
色々やりましたけど、どれが決め手になったかを調べている時間が
現在ないので適当に列挙しておきます。そのうちまとめます。
・GLSurfaceViewをextendsしているクラスに、onPause、onResumeをOverride
GLSurfaceViewでは、この2つだけはOverrideが可能です。
実際のところは、ここでウィンドウの再表示処理を記載する必要があります。
(ホームボタンを押して、アプリが収納されてしまった場合など)
とりあえずは、onPauseに以下のような処理を。
@Override public void onPause(){ this.queueEvent(new Runnable() { public final void run(){ // OpenGLの終了処理 endLoop(); } }); super.onPause(); } public void endLoop() { synchronized (th) { // ループを抜ける setLoopflg(false); } try{ // スレッドの終了を待つ th.join(); } catch( InterruptedException ex ){ Thread.currentThread().interrupt(); } th = null; }
突っ込みどころは多いソースコードですが、適当にこんな感じで。
ちなみにこの「th」スレッドオブジェクトではOpenGLの処理部分を動作させてます。
このスレッドの終了フラグが「setLoopflg」で下ろされ、スレッドの最後で
NDK側の最上位クラスが解放されるようになっています。
後はそれぞれのクラスのデストラクタで解放処理や
deleteTextureの処理を行っています。
この辺もちゃんとトレースして調べないとね。
OpenAL外した……
なんか検索ワードでもよく引っかかるこの単語のライブラリですが
どうにも動作遅いんで外しちゃいました。BGMはMediaPlayerで、
SEはSoundPoolつかって再生しています。
MediaPlayerって、何かちゃんと終了されないから好きじゃないんですけど……。
NDKが必ず解放されるようにした
Android NDK の初期化と dll の分離 - ホイール欲しい ハンドル欲しい
こちらのサイト様を参考に、NDKライブラリの間にダミーを作り、
その中で適切にload/unloadされる形としました。
以前にも、windowsでBluetooth使うときにこちらのサイトにはお世話に……。
こちらのサイトを参考に作った際には、良く関数名の修正漏れなどで
コンパイルエラーを頻発させました。ご注意を。
多分この対応の中の何かが、もしくは全てが干渉し合って
直ったんじゃないかな? と思ってます。