不要になった画像データをメモリからクリアする方法があると信じなければなりませんが、徹底的な検索にもかかわらず、解決策を見つけることができません。スタックとgoogleandroiddevリストの両方に、OOMエラー、特に「ビットマップサイズがVMバジェットを超えている」に関する質問がたくさんありますが、それでも明確な答えはわかりません。
デバイスにはハードメモリの制限があることを理解しています。また、大量の画像データを読み込んで表示またはキャッシュすることは現実的ではないことを理解していますが、不要になったデータを破棄する必要はありません。
たとえば、ネイティブギャラリーアプリの動作の多くをエミュレートする、この非常に基本的な架空のアプリを想像してみてください。
- ユーザーがリモートサーバーからの画像を閲覧できるようにする画像ギャラリー。
- そのサーバーには任意の数のイメージが存在する可能性があります。
- このアプリは一度に1つの画像を表示し、ユーザーはボタンを押すかスワイプすることで一度に1つの画像を前後に移動できます。
- 一度に最大3つの画像がレンダリングされます(したがって、ユーザーはスワイプすると現在の画像のすぐ左または右にある画像を見ることができます)。他のすべての画像データは破棄する必要があります。
- 画像は、URL.openStreamとDrawable.createFromStreamまたはBitmapFactory.decodeStreamを使用して読み込まれます。ストリームは適切に閉じられます。
- 画像は、フェッチされる前にサーバー上で適切なサイズになります。
- ロードはAsyncTasksで行われます。(タスクが不完全な画像から離れたために)不要になったタスクはキャンセルされます。AyncTask内のすべての参照はWeaklyReferencedです。
- 画像が不要になると、次の方法で「クリア」されます。
- getBackground()。setCallback(null)
- リスナーはnullに設定されます
- setImageDrawable / Bitmap(null)
- removeView
私が知っているすべての提案手法を考慮に入れたこの単純な構成は、ある時点で必然的にOOMエラーでクラッシュします。BitmapFactory.Options inSampleSizeとinPreferredConfigを使用すると、必然的に遅延しますが、永久にではなく、画質が犠牲になります。この例では、リモートイメージを使用しましたが、/assets/または内部メモリなどに保存されているイメージに問題があります。
ある時点でX量の画像データを表示でき、その画像データをメモリから削除するためのすべての手順を実行すれば、後で同じ量のデータを表示できるようになります。以前に起こった。
この問題についての質問が非常に多いので、標準的な解決策を文書化してもらいたいと思いますが、ある場合はそれを見つけることができません。Romain Guyが投稿した回答を見たことがあります。彼は、他の点では彼の知識に非常に寛大で、コミュニティで活発に活動しているようです。わかった。どうやってか教えて。
また、System.gcはこれを支援するものではありません。私はbitmap.recycleも知っていますが、私が間違えない限り、これはこの方法では使用できません。
私は何か基本的なものが欠けていますか?使用されなくなった画像データを破棄する方法はありますか?簡単なフォトギャラリーを作成するために上記に欠けているものは何ですか?組み込みのギャラリーアプリがNDKではなくフレームワークを使用していると仮定すると、方法が必要だと思います...
TYIA。
/この質問は、AndroidデベロッパーのGoogleグループリストにも投稿されています。