2

我已经使用内存 LRU 缓存在我的 android 应用程序中缓存位图。但是在将一些位图加载到 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

4 回答 4

2

如果您的应用使用 android:largeheap="true",

永远不要使用Runtime.getRuntime().maxMemory(),因为你很可能会比availabe和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)
于 2014-02-20T16:09:30.370 回答
1

Out of Memory Exception当位图超过可用的虚拟内存时会导致,一个好的做法是位图的回收。

  bitmap.recycle();

在这里阅读更多

何时应该使用 LRUCache 回收位图?

Mark Murphy 先生回答了一个问题。

于 2014-02-20T16:10:29.253 回答
0

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

于 2014-02-20T16:03:59.627 回答
0

当您遇到 Exception 时,您应该必须清除缓存并再次下载。检查以下功能以在内存超出时清除缓存

    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;
    }
}
于 2014-08-06T13:27:11.257 回答