【问题标题】:How can I optimize memory usage with lots of Bitmaps?如何使用大量位图优化内存使用?
【发布时间】:2011-10-15 20:06:46
【问题描述】:

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

是否有可能进一步扩大堆大小或者使用 OpenGL 来解决这个问题?谢谢。

【问题讨论】:

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


    【解决方案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); 
    

    AsyncImageLoader 类在这里

    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;
    }
    }
    

    【讨论】:

    • 您好,surendra,感谢您的建议。问题不在于加载,而在于图像全部加载到堆中。我通过使用 Gallery View 解决了这个问题,这几乎和我之前的解决方案一样好,但在内存方面要好得多。
    【解决方案2】:

    似乎没有办法降低 ARGB888 位图使用的内存,所以我决定使用 Gallery View 而不是 ScrollView。这对于内存管理要好得多。对于那些想知道为什么我不一开始就这样做的人 - 好吧,在我看来,ScrollView 看起来更酷,而且我不太喜欢 Gallery View 的整个中心对齐,但我会忍受的。谢谢!

    【讨论】:

      猜你喜欢
      • 2014-05-05
      • 1970-01-01
      • 2019-02-21
      • 2014-04-25
      • 1970-01-01
      • 2011-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多