我正在为我的应用制作一个简单的照片库。但我有一些非常烦人的内存泄漏,我不知道如何处理它们。
你能帮助我吗?我在其他问题上搜索,但根据答案,我似乎做得对。当然,我不是。我的代码:
我正在使用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;
}
}
任何线索? 提前谢谢。
答案 0 :(得分:1)
如果原始bmp尺寸大于imageview,我建议更改inSampleSize 2或4。你说有时图像大于2000x2000。这可能会导致内存问题。
答案 1 :(得分:1)
在标记
中的项目的清单文件中添加以下行<强>机器人:largeHeap = “真”强>
对于EX:
<application
android:name="com......"
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:theme="@style/CustomActionBarTheme">
这有助于您为应用程序提供更多内存