LiveWallpaperでプレビュー表示から設定したときにOutOfMemoryエラーが起こりやすい原因を調べてみました。
新規設定
LiveWallpaperをプレビューで表示
-
- プレビュー上でLiveWallpaperアプリ起動
既に設定されている状態での設定し直し
LiveWallpaperをプレビューで表示
-
- プレビュー上でLiveWallpaperアプリ起動
原因
新規設定のLiveWallpaperをHomeに設定する際の少しの間ですが、プレビュー上のアプリとHome上のアプリが同時起動される状態になります。
たぶんLiveWallpaper作成時にブチ当たる一番の壁がコレ、Create時に読み込みを行うリソース分がヒープ領域に乗ってきます。そして、OutOfMemoryですよ。
解決方法案
「Create時に読み込むのを避け、一度画面が表示されプレビュー用アプリがonDestroyされた後に読み込み始める。」が一番良さそう。
私が取った対策
Create時に読み込むんだけどエラーが出たら処理をスルーさせ、二度目のonVisibilityChangedがコールされたときに読み込むように作りました。
二度目のonVisibilityChangedと言うのがミソで、一度目はonCreate時でまだ画面に表示されてない状態で呼ばれます。そして二度目はプレビュー上のアプリがonDestroyされ、Home上のアプリが画面上に表示された時に呼ばれます。
フラグでも持たせてやれば簡単に実装できますね!
気になる点
この対応をする前にNexusOne(2.2)とDesire(2.1)で検証してみたところ、DesireではOutOfMemoryが頻発し、NesusOneでは一度もOutOfMemoryになりませんでした。
スペックはほぼ同等なので、たぶんOSのバージョンによるものかと思われます。ライフサイクルに変更はありませんでしたが、内部的なヒープの持たれ方が変わったのかJITのお陰なのかは分かりません*1。
ただ、今回の教訓としては2.2で動くからと言って2.1で動くとは限らない...またバージョンかイヤになります。
*1:そもそもメモリに良い影響与えるの?