Android一覧

メモリ内画像の表示(WebView)

WebViewを用いるとテキストと画像を同時に表示することが簡単にできます。
この際、画像データはすでにファイルとして端末内のどこかやURLによってどこかにすでにあることが多いです。

今回は、データはすでにメモリ上に展開されていて画像ファイルとして存在していない状況で、Android端末で表示する際のテクニックになります。

やり方

すでに画像データはバイト配列で用意できているとします。
これをBase64でエンコードし、HTMLのimgタグ内にセットします。
このとき、imgタグ内にセットする文字列は次のような形になります。

プログラム例

これで文章中に画像データが含まれ、WebViewで表示できるようになります。
WebViewで画像表示の利点は、このようにメモリ内に作った画像を表示できることと、TextViewに画像を表示するよりも手軽なことと、アニメーションGIFを使えることでしょうか。

参考

isherの日記 – WebViewで動的に画像を設定する方法」を参考にさせていただきました。


タブレット復活

いろいろとありましたがようやくICONIA TABが復活できました。
現時点では日本語公式ファームウェア 3.1 にして使用中です。

前回にデバッグができないようになってしまったという点についてですが、ホスト環境が悪かったようで再構築したところデバッグができるようになったことを確認できました。
ホスト側のeclipse workspaceを変更したり移動したりということがあったので、その影響を受けてしまったようです。
同様の問題に悩んだ際には、環境を一つずつ確認していくのもよさそうです。
(正しくデバッグできないのが正解で、たまたま動いていたGalaxyS2がおかしかったという結論)

これでひとまず安心して開発をやれそうです。


カスタムファームに入れ替えた

こんな状態じゃ使えない!と思い立ってとうとうICONIA TAB A500にカスタムファームをいれることにしました。
こんな状態じゃ使えないって部分は先日の日記を参照で。

カスタムファームを入れる際には慣れていないためいろいろと苦労しました。完全に文鎮化しなかったのはよかったです。大雑把ですが以下のような手順でファームを入れ替えました。

  1. rootをとる
  2. Acer Backup recoveryをインストール
  3. ツールから再起動
  4. microSDに保存しておいたファームウェアに入れ替える

これで 3.2.1の公式ではないものに変更してみました。
その結果、NativeActivityを使用したアプリは動いたので、先日の動作不良の原因はAcerが提供する公式ファームウェアにあるといえそうです。

これで使用していけば問題は解決するように思えたのですが、1点だけどうにもならない点がありました。それは今まで使えていた割と理想的なネイティブのデバッグができない状況になってしまったことです。ndk-gdb-eclipseらはうまく動くのですが、eclipse上からソースコードレベルのデバッグができない感じです。

公式が出しているOTA相当のROMに入れ替えてみたのですが、復帰しませんでした。ちなみに、入れ替える際には元の環境をバックアップとっていなかったので、元々の3.2.1でどうだったかは不明です。

ひとまず ndk-gdb を起動して、コンソールでgdbコマンドを叩いていくくらいには動作できることがわかっているので、ここらで折り合いを付けるしかないかなと思っています。


3.2.1の問題か?

うちのICONIA TAB A500を Android 3.2.1 に更新してから NativeActivity を使ったものが起動しなくなった。
うーん、3.2.1の問題なのか、機種固有の問題なのか切り分けてみなきゃなぁ・・・。

NativeActivity がサポートから外れる・・・とかだったら困るなぁ。

 

とりあえず、エミュレータで試してみたところ問題なく動いた。
この点から考えるに ICONIA TAB A500での問題のように感じる。もうちょっと実機で同様の何かで確認してみようと思う。


Tegra2での不具合

Tegra2でだけ特定のエラーメッセージが出てうまく動かないということに悩まされていました。調べてみても、日本じゃ該当なし、海外で報告があるけどよくわからないまま終了というやっかいな状態でした。

それが今回ようやく解決方法含めてわかったので、記事にしてみました。
戦っていたエラーメッセージは 、P1202: Texture’s gl states do not match with shader’s というものです。

エラーメッセージのタイミング

このエラーメッセージはどこで出てくるのかを調べてみると、 GL_VALIDATE_STATUS を引数に、glGetProgramiv を呼び出して、エラー時に glGetProgramInfoLog を呼び出して、その中のメッセージに格納されて表示されてくるようです。

つまり、glValidateProgram の部分がまずい!ということです。
このAPIの説明を確認すると、現在のシェーダーが正常に実行できるか検証するという意味合いのAPIとのことです。
通常は、glUseProgramした後で、 glValidateProgramで実行できるかを確認する、という使い方を想定していると思われます。決して、シェーダーのglLinkProgram後に検証というものではなさそうです。

つまり、実行するときの状態がそろった上で 検証をしなくてはなりません。
そのため、使用するテクスチャ の状態が正常か、サンプラーの状態は正しいか、などすべての条件が考慮されます。 今回引っかかってしまったのは、テクスチャを使うシェーダーで、テクスチャを設定していない(バインドしていない)状態で、glValidateProgram を呼び出してエラーとなっていました。

このメッセージで悩まされた場合には、その時の状況が何か正しくないのだと思います。設定されている各種状態を丁寧に見た方がよいと思います。
なお、Mali-400, Adreno, PowerVR あたりの ドライバではこのあたりはきちんと検証してくれないのかエラーとなることは今のところありませんでした。(故に発見がおくれた&Tegra2のバグだ!と考えてしまいました)

最後になりましたが、Javaからだとタイミングが悪くてもこれらのエラーメッセージはでないようです。


NDK r7が出てた

ついさっきみたら、Android NDKのrevision 7が出てました(android-ndk-r7)。
Android 4.0 が発表された上旬ではまだでしたが、遅れて登場したようです。

いくつか更新を見ていて気になったポイントを列挙してみます。

  • マルチメディア関連の拡充。使えるのは、API Level 14以降のものっぽいですが。 
    • ネイティブでOpenMAX ALのサポートが追加。
    • OpenSL ESでも圧縮オーディオ(mp3,aac)をwaveにデコードできる機能とか。
  • CCacheのサポート。
  • これで巨大なプロジェクトのリビルドが高速に.

実験的なサポートでも魅力的なものがありました。

  • Windows環境でCygwinなしでビルドできるように ndk-build.cmd の追加。
    ただし、ndk-gdbの使用には cygwinが必要な模様です。 

なかなかおもしろくなってきました。Windows環境での開発という点も考慮されるようになってきたのはうれしいですね。このあとndk-gdbの完全なるWindows版が提供されるようになってきたら、cygwinとオサラバできそうです。


Androidでネイティブデバッグ

Androidでネイティブコードのデバッグが問題なく行える機種情報です。

前回には方法を説明したので、 今回はデバッグに使える機種情報をさらしてみたいと思います。
また、できない機種情報も一緒に書いておきます。デバッグを目的とする場合には、この情報が役立ってくれると幸いです。

ネイティブのデバッグに使用できない

  • GalaxyS
  • Lenovo Ideapad tablet A1

ネイティブのデバッグで使用できる(gdb動く) 

  • GalaxyS2
  • Nexus S
  • xperia ray
  • IconiaTab A500
  • Xperia acro
  • GalaxyNexus
  • GalaxyS3
試してみてほかの機種でうまくいった方の情報をお待ちしています。
2012/10/13 – 機種情報を追加しました。

Androidでネイティブデバッグ(実機でデバッグも) -その2-

前回の設定により JNIの開発環境としてもEclipseが使えるようになりました。
ビルド自体もcygwinからndk-buildコマンドを実行しなくとも、EclipseからC/C++(NDK)の含めてビルドや実行を することが可能になりました。

今回は、目標でもあるネイティブコードのソースコードレベルデバッグについて、設定方法&実行方法を説明してきます。

使用するもの

  • 前回構築した各プラグインの導入されたEclipse (indigo)
  • 前回サンプルとして使ったMyApplicationのサンプルコード
  • Android実機
    • 実機でデバッグできるようになると感動です

サンプルは手を加えて使うので、似たようなものが用意できれば特に前回のものと同じである必要はありません。
今回単にデバッグ対象というだけで使用します。

Androidの実機についてですが、GalaxyS だけはうまくいきませんでした。
ICONIA Tab A500、Nexus S、GalaxyS2 では、このデバッグ方法がうまくいくことを確認できています。

ネイティブデバッグのための設定変更

まず、AndroidManifest.xml で Debuggable を true にしておきます。これはデバッグする対象に必須です。

デバッグの構成を変更(あるいは新規作成します)。
この新規作成するデバッグの構成は、”C/C++ Application”のデバッグ構成です。
Debug Configurationのウィンドウを開き、”C/C++ Application”カテゴリを選択し、左上の新規作成のボタンを押して構成を作成します。

作成した構成を選択し、画面中央部分の、”Using GDB(DSF) Create Process Launcher “の部分のリンクできる場所をクリックします。新しいウィンドウが開き、以下の図に示すように “Standard Create Process Launder”を選択します。

このウィンドウを閉じて、設定を再開します。
Mainタブの部分では、デバッグ対象の .so 名が表示されています。これを修正します。
プロジェクトのパス内の obj/local/armeabi の中にも同様の .so が作成されています。
この場所で、後ほど作成される app_process というファイルを使用するのでこれに変更します。
→ “obj/local/armeabi/app_process”

続いて、Debuggerタブを開きます。
Debuggerが gdb/mi になっているので、 gdbserver に変更します。
GDB debugger の部分には、android-ndkに入っていたgdbを選択させます。
→ (NDKの配置先 ex:android-ndk-r6b)toolchainsarm-linux-androideabi-4.4.3prebuiltwindowsbinarm-linux-androideabi-gdb.exe

GDB command file の部分には後ほど作成する gdb2.setup を設定します。
これも obj/local/armeabi の中にできあがる予定となっています。
このDebugger Optionsの中のConnection タブを開きます。
この中の Type を  TCP に変更します。そしてPort number を 5039 に変更します。忘れやすいので注意

ここまでの設定の画像を一応張っておきます。こんな感じになっているでしょうか。

次に、Android NDKに含まれている ndk-gdb のファイルを修正します。
とりあえず、ndk-gdbはコマンドではなく単にスクリプトなので、コピーしてから編集します。
このファイルを ndk-gdb-eclipse を名前を変えてコピーします。コピー後、適当なテキストエディタで開いて、末尾付近のコードを修正します。

となっている部分を、以下のようにしてコメントアウトにしておきます。(先頭に # を入れるだけ)

さきほど後で作成するといった各ファイルをここで準備します。作成するためにまずJavaのコードで、.soがロードされたあたりでブレークポイントを張ります。前回のサンプルならば、onCreateにはいった直後あたりでとめます。この設定をしてから、MyApplicationをデバッグ実行します。

この止めてある状態で、cygwinを起動し、このプロジェクトのある場所までカレントディレクトリを移動します。
そこで、ndk-gdb-eclipseコマンドを実行します。 エラーがなければしばらくしてコマンドが終了します。

このときに、obj/local/armeabi ディレクトリをのぞいてみると、app_process, gdb.setup というファイルができあがっています。これをデバッグに使用していきます。
app_processはそのまま使用するので放置、ここでは gdb.setup を gdb2.setup としてコピーします。
コピー後、適当なテキストエディタで開き、 最終行付近にある “target remote :5039” という部分を削除して保存し直します。

ここまで準備ができたら先ほどデバッグ実行したコードは終了し、cygwinのウィンドウも終了させておきます。

デバッグの確認

さて、準備が整ったので、ソースコードレベルでバッグの動作確認をしてみます。
前回のコードよりもう少しC/C++のコードを追加して、変数の値が見れることやブレークポイントの設定が可能であることをみていきましょう。

ソースコードの変更

デバッグの効果をみてみたいので、ソースコードを変更します。

デバッグの方法

このように変更してアプリケーションをビルドします。
Javaの部分の onCreateにはいった直後あたりでブレークポイントを設定し、デバッグ実行を行います。
ブレークポイントで停止したら、cygwinを開き、プロジェクトのディレクトリまでカレントディレクトリを移動させて、ndk-gdb-eclipse コマンド(スクリプト)を実行します。
問題なく実行完了したら、Eclipseで 先ほど作成した C/C++用のデバッグ構成 で実行します。
(Debug As などで ウィンドウを開いて、C/C++ Application内の構成を選択して、Debugボタンを押します)

gdbデバッガを起動させている途中で、エラーが出ると思いますが、これは無視して先に進むことが可能です。エラーの内容としては main関数でstopする予定だったのに、その関数がないよ、という意味合いのものです。
“Target request failed: Parsing Error” というメッセージで出てくるのでどきっとしますね・・・。

うまくいっていると、Consoleウィンドウの部分に gdb が起動していることが見て取れます。

ここまでくると、C/C++のソースコードにブレークポイントを張ることが可能になります。さきほどのソースコードで, GlobalCounter++ としている部分にブレークポイントを設定し、onCreateで止めていた実行を再開させてみます。
すると、 GlobalCounter++ のブレークポイントまで実行され、停止します!

GlobalCounterの値が0であったり、env, thiz の値がなにやらとれていたり、コールスタックを確認することができたり。ソースコードレベルでのデバッグが可能となっていることが確認できると思います。
この先、ステップ実行(Step Over)をして、bufの値を確認できるところまでやってみましょう。

ステップ実行ではgdbが裏でガリガリと動いている様子がconsoleのウィンドウを見ても確認できると思います。それゆえ、結構重い処理となっています。return文のところまできたら、bufに値が格納されているのが無事確認できると思います。

まとめ

2回ほどの記事で、AndroidのNDK、C/C++の開発コードにおけるネイティブソースコードレベルデバッグの方法を説明してきました。これにより、今まではprintf文か、コンソールでgdbを実行しながら動作を確認する方法しかなかったのが、GUI上でソースコードを見ながらデバッグすることが可能となりました。

VisualStudioではWinGDBを入れれば今回のことと同様のことができますが、今説明した方法はすべてフリーの環境で構築されています。動作が遅い点はありますが、これはこれで非常に使えるものだと思っています。

既知の問題点とか

ステップインの実行がなにやら怪しいです。eclipseのデバッグ仕様なのか、引数評価、関数ジャンプのための準備、という単位でステップ実行をしているようです。そのため、関数の中に入りたいタイミングでステップインのボタンを押しても、なかなか目的の関数に入れないということが起こります。
対処法は、目的の関数に到達するまでステップインを実行し続ける、ということになります。あるいは、目的の関数先頭にブレークポイントを設定してしまい、実行を再開させる方法でもよいと思います。

フリーな環境構築ですし、ある程度不便なのは仕方ないのかもしれません。

次回以降のデバッグの方法

同じプロジェクトの2度目以降のデバッグ方法は以下の方法でできます。ちょっとは手間ですが、初回ほど大変ではありません。

  1. ビルドし直した後、onCreateで停止させる
  2. ndk-gdb-eclipse を起動させる
  3. Eclipseで C/C++用のデバッグ構成でデバッグを開始させる
  4. onCreateで止めていた実行を再開させる

別のプロジェクトの場合には、C/C++用のデバッグ構成を作成するあたりから、設定が必要になります。

参考文献

ここまで到達できるのに、いくつか参考にしたページがあります。この情報がなければここまで便利に使えるようにならなかったと思います。


Androidでネイティブデバッグ(実機でデバッグも) -その1-

AndroidのC/C++を使ったネイティブコード(JNI)を、ソースコードデバッグできるように環境を整えることができました。環境にも若干左右されるようですが、概ねうまく動いてくれるようです。VisualStudio上ではなくEclipse上でではありますが、C/C++のソースコードレベルでブレークポイントを張ったり、変数を覗き見できるようになることは、開発のしやすさ向上につながると思います。

必要なもの

ここでは、Windowsでの開発環境を想定しています。以下のものがすでに整っているという前提で以降説明していきます。また、NDKのセットアップに関してはコマンドで ndk-build を実行して .so ファイルは作れる環境まで仕上がっているということを事前条件としています。

  • Eclipse
    • JavaによるAndroid開発環境が整っていること.
    • ここに、CDT, Sequoyah プラグインを入れていきます。
  • Android-SDK, NDK
  • cygwin

Eclipseの環境を準備する

EclipseでC/C++を扱うためにプラグインを導入します。
必要なプラグインは C/C++ Development Tools (CDT)です。
これは、Eclipseの [Help] => [Install New Software] と開き、”Work with”の部分に、”Indigo – http://download.eclipse.org/releases/indigo” となるように選択するか入力するかします。
すると一覧が出てくるので、ここで”C/C++ Development Tools”を選びます。
(“Group items by category”を外しておいた方が見つけやすくなるかもしれません)
チェックを入れて、このプラグインをインストールします。
インストール後には、Eclipseの再起動が必要になります。

続いて、Sequoyah プラグインを入れます。
先ほどと同様に、”Install New Software”から、”Work with:”の部分で以下のURLを入力します。
”http://download.eclipse.org/sequoyah/updates/2.0/”
そして、”Group items by category”のチェックを外してしばらく待つとプラグインの一覧が出てきます。
すべてにチェックを入れて、プラグインのインストールを行います。これもまたインストール後はeclipseの再起動が必要です。
[Window] => [Preferences] を開き、”Android”カテゴリ内の “Native Development” を開きます。
すると、NDK Location を入力する場所があるので、ここにNDKを展開したフォルダを指定しておきます。

動作チェック

ここまでの段階でAndroid Javaプロジェクトに対して、マウス操作でC/C++コード(JNI)の追加ができるようになっています。それを確認してみます。

まず適当なAndroidプロジェクトを作成します。

プロジェクトを作成した後、パッケージエクスプローラーで、作成したプロジェクトを選択した上で、右クリックします。
その中のメニューで、 “Android Tools”という項目の中に、”Add Native Support” という項目があります。
以下にスクリーンショット で示します。

これを選択すると、cppによるJNIのサポートが追加されます。
デフォルトで作成し、その後パースペクティブが”Native Android Perspective”に切り替わります。

こんな感じになっているので、cppの部分にJavaと接合するJNIのコードを書いていくことができます。

ここでは、hello-jniのコードと同じようなものを作成してみることにします。

コード loadLibraryしている部分の、”MyApplication”は自分の.soのファイルの先頭lib, 末尾.so を除いた部分を指定します。今回適当に作成したのでこのようになっています。各自の環境に合わせて変更する必要が出てくると思います。

プロジェクトのビルド

Project Explorerで、今回のプロジェクトを選び、右クリックすると”Build Project”という項目があります。
これを選択すると、JNIの部分のC/C++コードをビルドすることができます。

ビルドした結果は、Consoleのウィンドウに出てきます。ここで問題なく .so が生成されたかを確認することができます。ちなみに、通常のJavaアプリケーションのように実行ボタンを押したときでも、必要に応じてJNI部分のビルドコードは実行されるようです。

いつものように実行ボタンを押して、問題なくJNIのコードが呼び出されて動くことを確認してみてください。
記事として長くなってきたので、デバッグ用設定部分は次回の記事に回します。

いくつかのQ&A

– ビルドに失敗する。ndk-buildが見つからないという感じ

この場合、Cannot run program “ndk-build”メッセージがConsoleに表示されているはず。NDKのディレクトリ位置にパスを通しているのにも見つからない場合、設定をちょっと変更することで回避できる。

これを解決するには、Project Explorerから対象プロジェクトを選択し右クリックして、プロパティを表示させます。その中に、C/C++ Buildという項目があり、Builder Settings のタブで、Builder のコマンドを変更すれば一応解決することが可能です。

Use default build command のチェックを外し、cygwinのパス形式でndk-buildの場所を特定し、bashコマンドの引数として渡してあげればよい。

– “Build Project”が見当たらない or 前述のC/C++ BUildが見つからない

おそらくパースペクティブが Native Android Perspective になっていないからです。
一度確認してみましょう。


Androidアプリのライフサイクル&再開処理

ネイティブコードでメインの処理を行うとして、Javaの部分は単にActivityという入れ物にしか使わない、という感じでアプリケーションを作成することを考えている。今のところOpenGLESをつかっていて、Android特有の問題に悩まされている。

  • 複雑なライフサイクルで、OpenGLのコンテキストが再生成されている
  • その再生成のタイミングで今まで使用していたリソースが無効状態となる
  • そもそもOpenGLなのに、DirectXのようなデバイスロストに似た症状が発生する

Androidの通常アプリのActivityは以下の図に示す遷移をたどる。この図はGoogleのAndroidのページにあるものと同じである。

調べてみたところ、ユーザーの操作によって、似たように見えていても違う遷移となる点も確認できた。

  • 起動後、ホームボタンを押す。その後もう1度起動させるケース
    • onCreate – onStart – onResume – (実行中) – onPause – onStop –  onRestart – onStart – onResume – (実行中)
  • 起動後、Backボタンを押す。
    • onCreate – onStart – onResume – (実行中) – onPause – onStop – onDestroy
  • 起動後、放置してスクリーンのタイムアウトなどでActivityが見えなくなる
    • onCreate – onStart – onResume – (実行中) – onPause – (スクリーン復帰) – onRestart – onStart – onResume – (実行中)
サンプルのアプリケーションでは surfaceCreatedあたりでシェーダーやテクスチャなどの初期化を行っている。これが上記のどの部分になるかを調べてみたところ、onResume の直後あたりになるようだ。そしてsurfaceChangedも同部分になるようだ。

一方で、surfaceDestroyedなる部分は、onPauseの後になる模様。onStopに遷移するタイミングで実行されるみたい。

このつくりだとアプリケーションが再び実行状態になる前には surfaceCreatedを通過するため毎回リソース生成が行われるので、問題なく画面描画ができることになる。リソースの破棄処理がどうなっているのか疑問は残るが。
たぶん、確実にリソース処理しようとすれば onPauseで一時解放しておくのがよく、surfaceCreatedのタイミングで再生成するのがいいんだろう。

さて、上記の遷移はあくまでJavaの部分でのActivityの各イベントハンドラで検知した感じの情報。
これを C/C++の部分でどうやろうか、というのが問題となってくる。従来までの作りをしているアプリケーションだと、最初に初期化して、アプリ内グローバルなインスタンスはアプリ最後まで生き残ることを想定している。このグローバルなインスタンスにはグラフィックスやサウンドの管理部分がいたりする。
書籍「Androidネイティブプログラミング」 にもある例だと、surfaceCreatedのタイミングで初期化を行い、onDrawFrameの部分でC/C++のメインループへ実行を飛ばしている。これの作りをそのままにしておくと、アプリの切り替えから復帰しようとした時には常に初期化処理から実行されることになる。2重初期化を検知してエラーとか出すような作りにしていれば、そこでエラーとなる。あるいは初期化から再スタートなので、先ほどまでのデータが残っていたりはしない。

さて、もう1度よく考えてみよう。

再初期化が必要なのはいったい何か。アプリケーションのデータは初期化してしまう必要はあるか?

そう。必要なのはデバイスにアクセスしているようなグラフィックスやサウンドの部分についてだけ。その他のアプリケーションがメモリに持っている各データ状態はそのままでいいはずである。画面遷移するまでに使っていたリソースを再度確保してあげるコードを用意して、ほかの状態から戻ってきたときにその部分を処理するようにすれば、理論上はそのアプリケーションは切り替え前の状態に戻るわけで問題なく再開が可能なはずだ。

では、リソースの解放や再確保の部分はどこで行うべきか。
個人的には次のように考えている。onPauseの部分でリソースの解放処理を行ってしまい、ほかのアプリケーションの邪魔をしないようにする。これにはリソースを減らしてあげることでAndroidシステムから真っ先に消される可能性を幾分か減らしてくれるはずだ。 そしてこのonPauseを通過したことを示すフラグを立てておく。
リソースの再確保の部分はどこに書くのか、実行するのか。これはonDrawFrameの中でやるか、surfaceCreatedあたりでやるかしか方法はなさそうである。理由はコンテキストの再生成が行われた後、ウィンドウが表示されていることなどその他の要因があるからである。どちらの部分にせよ、C/C++へのジャンプコードが入っているので、先ほど覚えておいたフラグを用いてonPauseを通過済みであるならリソースの再確保処理を行ってあげるコードを実行すればよいだろう。最後に忘れてはならない点は、このonPauseの通過フラグは onCreateのタイミングで確実にfalseを設定してあげること。

理由を説明すると、このフラグはおそらくグローバルに持つ感じになるだろう。Androidのシステムにおいてメモリイメージは再利用される可能性があるので、あるタイミングではこのフラグがtrueのまま最初から実行されレしまう可能性もある。一応onPause, onStopからonCreateへの遷移ではメモリ解放となっているが、onCreateでfalseにしてしまったほうが安全に思える。

まとめると、onPauseの部分で onLostDevice相当の関数を実装&実行させ、onResumeの後のsurfaceCreated/onDrawFrame内でonResetDevice相当の関数を実装&実行させれば、リソースの復帰が可能だろうと思われる。

AndroidのGLSurfaceViewが面倒を見てくれるのは、EGL,GLのコンテキストの再生成まで。それ以外のテクスチャやシェーダー、FBO,VBOなどは再生成を手動で行う必要がある。それはオールJavaで書いてあっても同様だ。