前回の実験の続き
前回のコメントでImageView#setImageDrawable(null)すればbitmap#recycleは不要という指摘を頂いたので実験
実験6 recycleしない
実験6-2 実験6の状態で画面の向きを変更
実験7 実験5の状態で画面の向きを変更
実験8 実験5の状態でモンキーチックなことを人力で
手順
MainActivity>BitmapActivity>MainActivity>BitmapActivity>GC>jhat
ソースを以下のように変更
public class BitmapActivity extends Activity { private ImageView image; private Bitmap bitmap; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.recycle); image = (ImageView) findViewById(R.id.imageView1); } @Override protected void onResume() { super.onResume(); bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.python_logo); image.setImageBitmap(bitmap); } @Override protected void onPause() { super.onPause(); image.setImageDrawable(null); // bitmap.recycle(); // bitmap = null; } public void onNextButtonClick(View v) { Intent intent = new Intent(this, NextActivity.class); startActivity(intent); } }
実験6-2 BitmapActivity表示中に画面向き変更
別に意地悪したいわけではないが、画面を縦横に変化させてみた
結果
1個目
jikken6_3-01.png
これはフォアグランドで動いているやつの様子
別段問題はなさそう
2個目
こいつは回収されてないやつ。
興味深いのはInstance data members:のbitmapがnullになっていて、imageはまだいる
ImageViewを覗くとこうなっている
mDrawable (L) :
どうやらBitmapの回収はされている様子。ただし、Activityは回収されていない。何かしらが参照しているのか?
BitmapActivityに戻ってReferences to this object:を見てみる
ImageViewがActivityを参照しているだけでなく、その他のViewの参照も残っている
実験7 実験5の最終状態で画面の向き変更
ソースを以下のように戻す
public class BitmapActivity extends Activity { private ImageView image; private Bitmap bitmap; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.recycle); image = (ImageView) findViewById(R.id.imageView1); } @Override protected void onResume() { super.onResume(); bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.python_logo); image.setImageBitmap(bitmap); } @Override protected void onPause() { super.onPause(); image.setImageDrawable(null); bitmap.recycle(); bitmap = null; } public void onNextButtonClick(View v) { Intent intent = new Intent(this, NextActivity.class); startActivity(intent); } }
実験8 実験5の状態で人力モンキー
何回も向きを変えたり画面遷移したりモンキー的な動作をする
結論
前回の結論と変わらず。
ImageView#setImageDrawable(null)
Bitmap#recycle()
両方やったほうがよさげ
あと、今回はImageViewとの連携だったけど、ImageViewを使わないケースもあるのでrecycleはしといた方がよさげ
釈然としないこと
今回のケースではActivityはBitmapを参照しているが、BitmapはImageViewで使っている以外はどこからも参照されていない。
なのでImageViewがただしく破棄されればActivityもGC対象になり、自動的にBitmapもGCされるのではないか?と思う。
実験6-2の段階で上手にActivityの参照がなくなれば破棄されそうなんだよね。そうなると指摘どおりBitmap#recycleは必ずしも必要ではなくなる。
もしかして、これを
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.python_logo);
をこうすると、いけるのかな?
bitmap = BitmapFactory.decodeResource(getApplicationContext().getResources(), R.drawable.python_logo);
とりあえず、実験はここまでにする。少しばかりの達成感と、二度とやりたくない気持ちを込めて終了。
shisei_ssiさん。コメントありがとうございました。