在我的Android应用中,我使用自定义ImageView类(横幅)来显示从Facebook事件中提取的图像。在运行应用程序时,我注意到在运行应用程序时有一个很大的堆大小(120 MB)。我使用MAT,我认为我已将其缩小到byte[]
,然后最终缩小到ImageView
。请查看下面的图片,看看我是如何得出这个结论的。
现在,我已经阅读了similar posts,我尝试使用WeakReferences回收我的位图,创建一个缓存,但似乎没有任何东西减少内存大小。 然而,回收我的位图给我一个错误,说我不能使用循环位图(我觉得这可能是一个暗示,因为它将我的位图保留在内存中?)。
应用程序在我的手机上运行缓慢(即使内存平均为100 MB,它甚至只表示CPU使用率为1.5%)。我将发布我的Banner子类以及如何下载图像以查看是否有人可以帮助我。
Banner.java
:
public class Banner extends ImageView {
public Banner(Context context) {
super(context);
}
public Banner(Context context, AttributeSet attrs) {
super(context, attrs);
}
public Banner(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = 400;
if (getDrawable() != null && getDrawable().getIntrinsicWidth() != 0){
height = width * getDrawable().getIntrinsicHeight() / getDrawable().getIntrinsicWidth();
if (height < 500)
height = 700;
}
setMeasuredDimension(width, height);
setColorFilter(Color.rgb(123, 123, 123), android.graphics.PorterDuff.Mode.MULTIPLY);
}
public void onDestroy(){
Drawable drawable = this.getDrawable();
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
Bitmap bitmap = bitmapDrawable.getBitmap();
bitmap.recycle();
}
this.setImageBitmap(null);
}
}
BannerLoader.java
:
public class BannerLoader{
private String url;
private WeakReference<ImageView> cover;
private LruCache<String, WeakReference<Bitmap>> mMemoryCache;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
public BannerLoader(String cover_url, WeakReference<ImageView> cover, Drawable defaultDrawable) {
this.url = cover_url;
this.cover = cover;
cover.get().setBackground(defaultDrawable);
mMemoryCache = new LruCache<String, WeakReference<Bitmap>>(cacheSize) {
@Override
protected int sizeOf(String key, WeakReference<Bitmap> bitmap) {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.get().getByteCount() / 1024;
}
};
new DownloadImage().execute();
}
public void addBitmapToMemoryCache(String key, WeakReference<Bitmap> bitmap) {
if (getBitmapFromMemCache(key) == null) {
mMemoryCache.put(key, bitmap);
}
}
public WeakReference<Bitmap> getBitmapFromMemCache(String key) {
return mMemoryCache.get(key);
}
class DownloadImage extends AsyncTask<Void, Void, WeakReference<Bitmap>>{
protected WeakReference<Bitmap> doInBackground(Void... params){
try {
final WeakReference<Bitmap> cachedBitmap = getBitmapFromMemCache(url);
if (cachedBitmap != null){
return cachedBitmap;
} else{
URL pictureURL = new URL(url);
HttpGet httpRequest = null;
httpRequest = new HttpGet(pictureURL.toURI());
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = (HttpResponse) httpclient
.execute(httpRequest);
HttpEntity entity = response.getEntity();
BufferedHttpEntity b_entity = new BufferedHttpEntity(entity);
InputStream input = b_entity.getContent();
WeakReference<Bitmap> bitmap = new WeakReference<Bitmap>(BitmapFactory.decodeStream(input));
addBitmapToMemoryCache(url, bitmap);
return bitmap;
}
} catch(Exception ex){
ex.printStackTrace();
}
return null;
}
public void onPostExecute(WeakReference<Bitmap> image){
if (image != null && cover.get() != null){
cover.get().setImageBitmap(image.get());
}
}
}
}
因此,作为一个例子,我下载了这样的图像:
new BannerLoader(tempEvent.getCover_url(), new WeakReference<ImageView>(thumb_image), context.getResources().getDrawable(R.drawable.placeholder));
感谢您的帮助!