hyoromoのブログ

iOS/AndroidもしくはCocos2dxネタを書いています

LiveWallpaper設定時のOutOfMemory発生原因

LiveWallpaperでプレビュー表示から設定したときにOutOfMemoryエラーが起こりやすい原因を調べてみました。

新規設定

LiveWallpaperをプレビューで表示
    • プレビュー上でLiveWallpaperアプリ起動
LiveWallpapserをHomeに設定
    • Home上でLiveWallpaperアプリ起動
    • プレビュー上で起動していたLiveWallpaperアプリが終了

1枚目

既に設定されている状態での設定し直し

LiveWallpaperをプレビューで表示
    • プレビュー上でLiveWallpaperアプリ起動
LiveWallpapser設定
    • プレビュー上で起動していたLiveWallpaperアプリが終了

2枚目

原因

新規設定の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:そもそもメモリに良い影響与えるの?