View Pager を使用して、アプリケーションでネットワークからダウンロードした画像を表示しています。画像の数は 5 ~ 20 です。ネットワーク操作には Volley ライブラリを使用しています。アプリは以前はあまりメモリを消費していませんでしたが、ビューページャーを追加した後、アプリは大量のメモリを消費し、このアクティビティを開くたびに、ヒープで使用されるメモリが増加します (ログメッセージから確認)。また、Eclipse メモリ アナライザーを使用して、リークがどこにあるかを確認しました。それは間違いなく、このアクティビティのビットマップと複数のインスタンスです。このアクティビティはGCされていないため、間違いなくリークがあり、いくつかの参照がこれをガベージコレクションから遠ざけています。ビューページャーの実装をここに追加しました。
public class ViewPagerAdapter extends PagerAdapter {
Context context;
public ViewPagerAdapter(Context context) {
this.context = context;
}
@Override
public int getCount() {
return photoReferences.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == ((RelativeLayout) object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
final ImageView im;
final ProgressBar pb;
View itemView = inflater.inflate(R.layout.place_photos_item, container, false);
im = (ImageView) itemView.findViewById(R.id.placeImage);
attributes = (TextView) itemView.findViewById(R.id.placeAttributes);
pb = (ProgressBar) itemView.findViewById(R.id.progressBarPhoto);
imageLoader.get(url, new ImageListener() {
public void onErrorResponse(VolleyError arg0) {
im.setImageResource(R.drawable.onErrorImage);
}
public void onResponse(ImageContainer response, boolean arg1) {
if (response.getBitmap() != null) {
im.startAnimation(AnimationUtils.loadAnimation(context, android.R.anim.fade_in));
im.setImageBitmap(response.getBitmap());
pb.setVisibility(View.GONE);
}
}
});
((ViewPager) container).addView(itemView);
return itemView;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((RelativeLayout) object);
}
}
また、screenBytes (screenWidth * screenHeight * 4) の 3 倍のサイズのビットマップ キャッシュを使用しています。4.3 を実行している Nexus 4 でテストしていますが、このデバイスではヒープ サイズが非常に大きいため、OOM 例外が発生することはありませんが、アクティビティを開くと、アプリは 100 MB を超えるメモリを使用する可能性があります (ほとんどのデバイスではクラッシュします)。何度も何度も、以前は何があっても約 16 ~ 20 MB のメモリを消費していました。これがキャッシュコードです。
public class BitmapCache extends LruCache<Object, Object> implements ImageCache {
public BitmapCache(int maxSize) {
super(maxSize);
}
@Override
public Bitmap getBitmap(String url) {
return (Bitmap) get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
}
誰かがリークをキャッチするために何をすべきか教えてもらえますか? View Pager または Volley の使用法に問題はありますか? Pager の移行にも満足していません。少し遅れていますが、それは関係していますか?
更新: これは MAT のスクリーンショットです。リークの可能性があります。これは、Volley ライブラリを使用するすべてのアクティビティにあります。私はたくさん読んできましたが、問題を解決できませんでした。ボレーがリークを引き起こしているのでしょうか、それとも私が何かひどく間違ったことをしているのでしょうか?