Android: 一時ビットマップで「リサイクルされたビットマップを使用しようとしています」というエラーが発生する 質問する

Android: 一時ビットマップで「リサイクルされたビットマップを使用しようとしています」というエラーが発生する 質問する

私のアプリはかなり大きな画像を読み込むことができます。メモリを節約するために、読み込みには一時ビットマップを使用し、変換後の最終画像には別のビットマップを使用するようにしています。

.....
finalBitmap.recycle();
finalBitmap = null;
Bitmap tempBitmap  = BitmapFactory.decodeStream(fin, ...);
finalBitmap = Bitmap.createBitmap(tempBitmap, ....);
imgview.setImageBitmap(finalBitmap);
.....

これで、tempBitmap は完了です。これは、デコードされた Bitmap を createBitmap の変換ステップに転送するためにのみ必要でした。つまり、次のようになります。

.....
tempBitmap.recycle();
tempBitmap = null;
.....

そして... tempBitmapのリサイクルが原因で「リサイクルされたビットマップを使用しようとしています」というエラーでクラッシュします。tempBitmapは表示されず、使用されるだけです。すぐそこに

ここで何が問題になっているのでしょうか?全体的に「finalBitmap」を使用し、createBitmap に管理を任せたほうがよいでしょうか (最終ビットマップ= ビットマップ.createBitmap(最終ビットマップ、…))? tempBitmap への継続的な依存関係がどのようなもので、それがこのような失敗を引き起こすのかわかりません。

編集:はい、ヌル割り当ては適切な結果になるようです。最終的にガベージ コレクションですが、この場合、一時ビットマップの recycle() がなぜそれほど問題になるのか不思議です。createBitmap() がそれへの参照を保持しているような印象を受けますが、なぜでしょうか。また、どのくらいの期間でしょうか。

ベストアンサー1

Androidから直接ドキュメンテーション:

ソース ビットマップの指定されたサブセットから不変のビットマップを返します。新しいビットマップはソースと同じオブジェクトである場合もあれば、コピーが作成された場合もあります。

createBitmap関数は、提供したビットマップを再利用する可能性があるようです。その場合、最終的なビットマップがそれを使用しているため、一時的なビットマップをリサイクルしないでください。できることの1つは、

if(tempBitmap != finalBitmap) {
   tempBitmap.recycle();
}

tempBitmap が finalBitmap と同じでない場合にのみ、tempBitmap をリサイクルする必要があります。少なくとも、ドキュメントではそのように説明されているようです。

おすすめ記事