如何防止LRU缓存中的内存不足错误

时间:2014-02-20 15:41:00

标签: android caching lru image-caching android-lru-cache

我在我的android应用程序中使用了内存LRU缓存来缓存位图。但是在将一些位图加载到LRU地图后,应用程序强制关闭说内存不足异常。我已经花了一整天的时间,但是没有找到解决方案,请任何人都可以帮助我,我很难坚持这个问题。谢谢你。

这是我的代码

final int maxMemory = (int) (Runtime.getRuntime().maxMemory()/1024);
final int cacheSize = maxMemory / 8;
bitmapHashMap = new LruCache<String, Bitmap>(cacheSize)
{
@SuppressLint("NewApi")
@Override
protected int sizeOf(String key, Bitmap value)
{
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2)
{
return value.getByteCount()/1024;
}
else
{
return (value.getRowBytes() * value.getHeight())/1024;
}
}
};

4 个答案:

答案 0 :(得分:2)

如果你的应用使用android:largeheap =“true”,

永远不要使用Runtime.getRuntime().maxMemory(),因为您最常使用的内存比可用性和OOM更多,而是使用内存类并按如下方式计算缓存的大小:

    /** Default proportion of available heap to use for the cache */
    final int DEFAULT_CACHE_SIZE_PROPORTION = 8;

    ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    int memoryClass = manager.getMemoryClass();
    int memoryClassInKilobytes = memoryClass * 1024;
    int cacheSize = memoryClassInKilobytes / DEFAULT_CACHE_SIZE_PROPORTION;
    bitmapHashMap = new LruCache<String, Bitmap>(cacheSize)

答案 1 :(得分:1)

当位图超过可用的虚拟内存时,会导致

Out of Memory Exception,这是一种很好的做法,就是回收位图。

  bitmap.recycle();

在这里阅读更多内容

<强> When should I recycle a bitmap using LRUCache?

马克墨菲先生回答了一个问题。

答案 2 :(得分:0)

您是否遵循这些指南? http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html 这是一个很好的教程,知道如何实现位图的存储。

答案 3 :(得分:0)

当你遇到异常时,你必须清除缓存并再次下载。当内存超过

时,检查以下功能以清除缓存
    private Bitmap getBitmap(String url)
            {
     File f=fileCache.getFile(url);
     //from SD cache
    Bitmap b = decodeFile(f);
    if(b!=null)
        return b;

    //from web
    try {
        Bitmap bitmap=null;
      //  URL imageUrl = new URL(url);

        /***/

        HttpURLConnection conn = null;
        URL imageUrl = new URL(url);
        if (imageUrl.getProtocol().toLowerCase().equals("https")) {
            trustAllHosts();
            HttpsURLConnection https = (HttpsURLConnection) imageUrl.openConnection();
            https.setHostnameVerifier(DO_NOT_VERIFY);
            conn = https;
        } else {
            conn = (HttpURLConnection) imageUrl.openConnection();
        }
        /***/



       // HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
        conn.setConnectTimeout(30000);
        conn.setReadTimeout(30000);
        conn.setInstanceFollowRedirects(true);
        InputStream is=conn.getInputStream();
        OutputStream os = new FileOutputStream(f);
        Utils.CopyStream(is, os);
        os.close();
        bitmap = decodeFile(f);
        return bitmap;
    } catch (Throwable ex){
       ex.printStackTrace();
       if(ex instanceof OutOfMemoryError)
           memoryCache.clear();
       return null;
    }
}