如何使用大量位图优化内存使用?

时间:2011-07-29 10:08:07

标签: android memory bitmap android-3.0-honeycomb out-of-memory

我正在开发一个可能能够将大量Bitmaps加载到ScrollView中的应用程序。但是,在某个时刻,只会有太多的位图,应用程序会因“内存不足”错误而崩溃。我在Honeycomb中使用了largeHeap选项。

是否有可能以更大的方式扩展堆大小或者使用OpenGL来解决此问题?感谢。

2 个答案:

答案 0 :(得分:1)

您可以通过异步加载图像来解决问题

使用此代码设置图像

AsyncImageLoaderv asyncImageLoaderv=new AsyncImageLoaderv();
Bitmap cachedImage = asyncImageLoaderv.loadDrawable(imgurl, new AsyncImageLoaderv.ImageCallback() 
{
public void imageLoaded(Bitmap imageDrawable, String imageUrl) {
if(String.valueOf(imageDrawable).equals("null")){}
else{
img.setImageBitmap(imageDrawable);
}
}
});
img.setImageBitmap(cachedImage); 

AsyncImageLoaderv类就在这里

import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class AsyncImageLoaderv {
private HashMap<String, SoftReference<Bitmap>> imageCache;

public AsyncImageLoaderv() {
imageCache = new HashMap<String, SoftReference<Bitmap>>();
}

public Bitmap loadDrawable(final String imageUrl, final ImageCallback imageCallback) {

if (imageCache.containsKey(imageUrl)) {
SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
Bitmap drawable = softReference.get();
if (drawable != null) {
return drawable;
}
}

final Handler handler = new Handler() {

@Override
public void handleMessage(Message message) {
imageCallback.imageLoaded((Bitmap) message.obj, imageUrl);
}
};

new Thread() {
@Override
public void run() {
try{
Log.d("ur",imageUrl);
Bitmap drawable = loadImageFromUrl(imageUrl);
imageCache.put(imageUrl, new SoftReference<Bitmap>(drawable));
Message message = handler.obtainMessage(0, drawable);
handler.sendMessage(message);
}catch(Exception e){Log.e("thread stellent",e.toString());}
}
}.start();
return null;
}

public static Bitmap loadImageFromUrl(String url) {
InputStream inputStream;Bitmap b;
try {
inputStream = (InputStream) new URL(url).getContent();
BitmapFactory.Options bpo=new BitmapFactory.Options();
bpo.inSampleSize=2;
//b=BitmapFactory.decodeStream(inputStream, null,bpo );
PatchInputStream patch=new PatchInputStream(inputStream);
b=BitmapFactory.decodeStream(patch);
return  b;
} catch (IOException e) {
throw new RuntimeException(e);
}

//return null;
}

public interface ImageCallback {
public void imageLoaded(Bitmap imageBitmap, String imageUrl);
}
}

class PatchInputStream extends FilterInputStream {
public PatchInputStream(InputStream in) {
super(in);
}

public long skip(long n) throws IOException {
long m = 0L;
while (m < n) {
long _m = in.skip(n-m);
if (_m == 0L) break;
m += _m;
}
return m;
}
}

答案 1 :(得分:1)

似乎没有办法降低ARGB888位图使用的内存,因此我决定使用Gallery View而不是ScrollView。这对内存管理来说要好得多。对于那些你想知道为什么我没有继续这样做的人 - 好吧,ScrollView在我看来看起来更酷,我不喜欢画廊视图的整个中心对齐,但我'我会和它一起生活谢谢!