LoginSignup
0
0

More than 1 year has passed since last update.

AnimationDrawableでOutOfMemoryErrorと出会ったときに試したこと

Last updated at Posted at 2023-02-02

メモです

setImageResource()が極端に重くなる。
android:largeHeap="true" は元々指定されていた。

リソースの置き場を確認

画像のスケーリングが処理としてはかなり重いので適切な場所に画像リソースを置いておかないとメモリを消費しがち。
drawable-XXdpiにサイズごとに分けて置くか、-nodpi, -anydpiといったところに配置してスケーリングが発生しないようにする。
https://developer.android.com/training/multiscreen/screendensities

画像を解放して続行

重くなる処理がわかっているのでcatchして発生後の処理を書くことができる。
下の例では重い画像を解放してやって続行している。アニメーションは表示させないことになる。
OOMが実際に出るまでに数秒は重くて操作できない時間が発生する。
処理が続行した直後に別の画像の読み込みに失敗することがある。
もちろん推奨はできないけどAndroidCodeSearchで検索すると割とヒットしたりするやり方。

OutOfMemoryErrorはExceptionを継承したクラスではないのでExceptionでまとめてcatchしようとしてもできない

try {
    imageView.setImageResource(animatable)
} catch(e: OutOfMemoryError) {
    imageView.setImageDrawable(null)
    return
}

自作FrameAnimationクラスを作る

先達が数人いたのでそれらを参考に。別記事にまとめます。
https://stackoverflow.com/questions/8692328/causing-outofmemoryerror-in-frame-by-frame-animation-in-android
https://gist.github.com/miensol/f4d6aa65fb09d627ae7e

自作アプリの中でいい感じにデコードする処理の詳細↓
https://developer.android.com/topic/performance/graphics/load-bitmap

試してうまくいかなかったこと

lowMemory検知

https://developer.android.com/topic/performance/memory#CheckHowMuchMemory
このへん

今回のケースではアニメーションの読み込み開始まではメモリ消費してないのでlowMemoryではfalseが返ってくるため回避不可だった。

空きメモリ量を取得して確認

OOMErrorのFatalログに確保しようとして失敗したメモリ量が出力されるので確認は可能なはず?
取得の仕方や取得できるメモリ情報にもいろいろあるらしくどれで判定したらいいかよくわからず。ちゃんと調べたら追記するか別記事にまとめます。

感想・その他

ハイエンド端末でも試験する方法が用意されていた
https://developer.android.com/topic/performance/memory-overview#stressapptest

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0