アプリの簡単なフォト ギャラリーに取り組んでいます。しかし、本当に厄介なメモリ リークが発生しており、その処理方法がわかりません。
皆さん、私を助けてくれますか? 他の質問で検索しましたが、回答によると、私は正しいことをしているようです。もちろん、そうではありません。
私のコード:
を使っTouchImageView
て画像を表示しています。
ViewPager
また、次のようにズーム機能をサポートするように拡張しました。
public class ExtendedViewPager extends ViewPager {
public ExtendedViewPager(Context context) {
super(context);
}
public ExtendedViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
if (v instanceof TouchImageView) {
/*
canScrollHorizontally is not supported for Api < 14. To get around this issue,
ViewPager is extended and canScrollHorizontallyFroyo, a wrapper around
canScrollHorizontally supporting Api >= 8, is called.
*/
return ((TouchImageView) v).canScrollHorizontallyFroyo(-dx);
} else {
return super.canScroll(v, checkV, dx, x, y);
}
}
}
この写真の一部は大きい場合があります (たとえば、2000x2000px など)。ビューresample
に追加する前に、このリサンプル関数を使用します。
public static Bitmap resample(int resourceID, boolean toFullScreen, Context c){
//set the width and height we want to use as maximum display
WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int targetWidth = display.getWidth();
int targetHeight = display.getHeight();
//create bitmap options to calculate and use sample size
BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
//first decode image dimensions only - not the image bitmap itself
bmpOptions.inJustDecodeBounds = true;
BitmapFactory.decodeResource(c.getResources(), resourceID, bmpOptions);
//image width and height before sampling
int currHeight = bmpOptions.outHeight;
int currWidth = bmpOptions.outWidth;
//variable to store new sample size
int sampleSize = 1;
//calculate the sample size if the existing size is larger than target size
if (toFullScreen || currHeight > targetHeight || currWidth > targetWidth){
//use either width or height
if (toFullScreen || currWidth > currHeight)
sampleSize = Math.round((float)currHeight / (float)targetHeight);
else
sampleSize = Math.round((float)currWidth / (float)targetWidth);
}
//use the new sample size
bmpOptions.inSampleSize = sampleSize;
//now decode the bitmap using sample options
bmpOptions.inJustDecodeBounds = false;
//get the file as a bitmap and return it
Bitmap pic = BitmapFactory.decodeResource(c.getResources(), resourceID, bmpOptions);
return pic;
}
そして、私の実装でそれを呼び出します。ここでは、ビットマップPagerAdapter
も試みます。recycle()
private class TouchImagePagerAdapter extends PagerAdapter {
@Override
public int getCount() {
return galleryImages.length;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
Context context = PhotoGalleryActivity.this;
TouchImageView touchImageView = new TouchImageView(context);
touchImageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
touchImageView.setImageBitmap(Helper.resample(galleryImages[position].getImgResource(), false, getApplicationContext()));
container.addView(touchImageView, 0);
return touchImageView;
}
@Override
public void destroyItem(ViewGroup collection, int position, Object object) {
TouchImageView ti = (TouchImageView) object;
BitmapDrawable bmpDrawable = (BitmapDrawable) ti.getDrawable();
if (bmpDrawable != null) {
Bitmap bmp = bmpDrawable.getBitmap();
if(bmp != null && !bmp.isRecycled())
bmp.recycle();
}
collection.removeView(ti);
ti = null;
}
@Override
public void destroyItem(View collection, int position, Object o) {
View view = (View)o;
((ViewPager) collection).removeView(view);
view = null;
}
}
手がかりはありますか?前もって感謝します。