标签: android-lru-cache

我什么时候应该使用LRUCache回收位图?

我正在使用LRUCache缓存存储在文件系统上的位图.我根据这里的示例构建了缓存:http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html

问题是我在使用应用程序时经常看到OutOfMemory崩溃.我相信当LRUCache驱逐图像为另一个图像腾出空间时,内存不会被释放.

当图像被驱逐时,我添加了对Bitmap.recycle()的调用:

  // use 1/8 of the available memory for this memory cache
    final int cacheSize = 1024 * 1024 * memClass / 8;
                mImageCache = new LruCache<String, Bitmap>(cacheSize) {
                @Override
                protected int sizeOf(String key, Bitmap bitmap) {
                    return bitmap.getByteCount();
                }

                @Override
                protected void entryRemoved(boolean evicted, String key, Bitmap oldBitmap, Bitmap newBitmap) {
                    oldBitmap.recycle();
                    oldBitmap = null;
                }
            };
Run Code Online (Sandbox Code Playgroud)

这可以解决崩溃问题,但是它也会导致图像有时不会出现在应用程序中(只是图像所在的黑色空间).任何时候我都会在Logcat中看到这条消息:Cannot generate texture from bitmap.

一个快速谷歌搜索显示这是发生,因为显示的图像已被回收.

那么这里发生了什么?为什么再循环图像仍然在LRUCache中,如果我只是在它们被删除后回收它们?实现缓存的替代方法是什么?Android文档明确指出LRUCache是​​可行的方法,但他们没有提到回收位图的必要性或如何做到这一点.

解决: 如果它有用给其他人,由接受的答案建议解决这个问题是不是做什么,我在做上面的代码示例(不回收的位图 …

android bitmap android-lru-cache

54
推荐指数
2
解决办法
3万
查看次数

使用Androids lrucache的示例

我需要帮助了解androids LruCache.我想用来将图像加载到我的gridview中,以便更好地加载/滚动.有人可以使用LruCache发布示例代码吗.提前致谢.

android android-lru-cache

37
推荐指数
3
解决办法
4万
查看次数

如何在Android中实现内存映像缓存?

到目前为止,我在Android中使用SoftReference Cache来处理图像.此缓存用于ListView中显示的图像,如果有足够的内存,应该有助于保存内存中未显示的项目图像.

这个问题是SoftReferences几乎是在最后一个硬引用发布的那一刻被垃圾收集的.结果是,从屏幕上移除的图像在那时被垃圾收集,并且如果用户在ListView中滚动回到该条目,则从内部电话存储器重新加载图像,导致复杂的延迟加载过程,从而导致频繁重绘列表和一般性能不佳.

软引用行为的错误请求表明这是预期的行为,您应该使用LRU-Cache来缓存此类内容.

知道我的问题.LRU缓存只会占用我允许的内存量.但如果应用程序需要大量内存,则无法释放内存.我应该如何确定我可以允许缓存使用多少内存,如果手机的内存情况变得紧张,有没有办法减少缓存的大小?

目前,图像缓存作为一种用于所有活动的全局图像存储保存在应用程序内.这将导致我的应用程序不断使用图像缓存的所有内存,即使我的活动在后台或被破坏.

android android-lru-cache

12
推荐指数
1
解决办法
1918
查看次数

使用get时LRUCache条目重新排序

我检查了LRUCache的官方Android文档,其中说:每次访问一个值时,它都会移动到队列的头部.将值添加到完整缓存时,该队列末尾的值将被逐出,并且可能符合垃圾回收的条件.我想这是双链表,它由缓存使用的linkedhashmap维护.为了检查这种行为,我检查了LruCache的源代码,并检查了get(K key)方法.它进一步调用map的get方法,该方法从底层hashmap获取值并调用recordAccess方法.

public V get(Object key) {
    LinkedHashMapEntry<K,V> e = (LinkedHashMapEntry<K,V>)getEntry(key);
    if (e == null)
        return null;
    e.recordAccess(this);
    return e.value;
}
Run Code Online (Sandbox Code Playgroud)

如果accessOrder设置为true(对于我的问题,我们假设它是),recordAccess方法依次将访问的条目移动到列表的末尾,否则它什么都不做.

/**
     * This method is invoked by the superclass whenever the value
     * of a pre-existing entry is read by Map.get or modified by Map.set.
     * If the enclosing Map is access-ordered, it moves the entry
     * to the end of the list; otherwise, it does nothing.
     */
    void recordAccess(HashMap<K,V> m) {
        LinkedHashMap<K,V> lm …
Run Code Online (Sandbox Code Playgroud)

java android linkedhashmap android-lru-cache

8
推荐指数
1
解决办法
424
查看次数

LruCache不工作

    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    final int cacheSize = maxMemory / 8;
    mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // The cache size will be measured in kilobytes rather than
                // number of items.
                return bitmap.getByteCount() / 1024;
            }
        };
    URL url = new URL("http://s2.goodfon.ru/image/260463-1920x1200.jpg");
    Bitmap bitmap = BitmapFactory.decodeStream((InputStream) url.getContent(), null, options);
    if(bitmap != null)
        Log.i("Success", "BITMAP IS NOT NULL");

    String key = "myKey";
    Log.i("Get is null", "putting myKey");
    mMemoryCache.put(key, …
Run Code Online (Sandbox Code Playgroud)

android android-lru-cache

7
推荐指数
1
解决办法
3948
查看次数

developer.android.com/training bitmapfun项目

我在我的应用程序中使用bitmapfun项目(),而我在测试这个时发现了一个问题.重现此问题的步骤如下:

  1. 打开wifi - >启动应用程序 - >下载图像(工作正常).
  2. 关闭应用程序(后退按钮),停用wifi - >激活数据网络 - >重新启动应用程序(仍然可以正常工作).
  3. 在下载所有图像之前,我关闭应用程序(后退按钮) - >停用数据网络 - >激活wifi.在此步骤之后,当我重新启动应用程序时,图像不会下载.

在logcat中,我看到所有图像都在imageWorker的cancelPotentialWork()中被取消,它们永远不会启动.我的猜测是,之前的bitmapworkerTask(负责下载)发生了一些事情,并且与新任务发生冲突.在我的应用程序按下时,我清除所有缓存.但这不是问题的原因,因为我也测试了原始bitmapfun中的相同场景,问题也出现了!我该如何解决这个问题?我还将项目的多线程更改为单个线程!有没有办法清除所有imageview引用并取消所有正在运行的任务?

对不起我的英语,并且没有提供有关bitmapfun项目性质的更多信息,但它会非常扩展我的问题!向我提问!

编辑:为了重现问题,每次使用菜单选项离开活动时,最好清除缓存.如果您按照步骤1-3进行一次,也不确定是否会出现此问题.也许你必须重复它们!

Edit2(附加帮助):当我开始没有问题的活动时,第一个图像的logcat如下:

04-24 02:31:56.400: D/ImageWorker(25625): doInBackground - starting work
04-24 02:31:56.400: D/ImageFetcher(25625): processBitmap - https://lh3.googleusercontent.com/--L0Km39l5J8/URquXHGcdNI/AAAAAAAAAbs/3ZrSJNrSomQ/s160-c/Antelope%252520Butte.jpg
04-24 02:31:56.400: D/ImageFetcher(25625): processBitmap, not found in http cache, downloading...
Run Code Online (Sandbox Code Playgroud)

当我开始有问题的活动时,logcat是这样的:

04-24 02:28:07.970: D/ImageWorker(24014): cancelPotentialWork - cancelled work for https://lh3.googleusercontent.com/--L0Km39l5J8/URquXHGcdNI/AAAAAAAAAbs/3ZrSJNrSomQ/s160-c/Antelope%252520Butte.jpg
Run Code Online (Sandbox Code Playgroud)

为什么在第二种情况下调用cancelPotentialWork时doInBackground永远不会启动?根据代码序列,这是应该执行的下一个部分!至少有任何人想知道我应该在哪里搜索错误吗?

android gridview android-asynctask android-lru-cache

6
推荐指数
1
解决办法
774
查看次数

Android LruCache 缓存大小参数

我正在尝试遵循关于 LruCache 使用的 2 年前的 android 教程,到目前为止我在谷歌上搜索的一些示例具有相同的方法,即传递一个转换为 KiB 的值(int)。

final int maxMemory = (int)(Runtime.getRuntime().maxMemory() / 1024); 
final int cacheSize = maxMemory / 8; //use 1/8th of what is available
imageCache = new LruCache<>(cacheSize);
Run Code Online (Sandbox Code Playgroud)

但是,从 Google 的文档中获取,传递的 int 值似乎转换为字节(来自 MiB):https : //developer.android.com/reference/android/util/LruCache.html

int cacheSize = 4 * 1024 * 1024; // 4MiB
LruCache<String, Bitmap> bitmapCache = new LruCache<String, Bitmap>(cacheSize) {
   protected int sizeOf(String key, Bitmap value) {
       return value.getByteCount();
   }
}
Run Code Online (Sandbox Code Playgroud)

我想知道哪个是正确的计量单位。任何答案将不胜感激..

android android-lru-cache

6
推荐指数
1
解决办法
2442
查看次数

为什么在使用android-support-v4时找不到android.util.LruCache.*?

我正在编写一个使用LruCache的项目,它包含在android-support-v4.jar compat库中.在使用JB的设备上运行时,代码运行正常,但是当我在带有GB的Droid X上运行它时,应用程序会因以下错误而死机:

I/dalvikvm(2459): Could not find method android.util.LruCache.put, referenced from method blah.blah.Utility.getBitmap
W/dalvikvm(2459): VFY: unable to resolve virtual method 2641: Landroid/util/LruCache;.put (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
D/dalvikvm(2459): VFY: replacing opcode 0x6e at 0x0026
... [repeats similar lines] ...
W/dalvikvm(2459): Unable to resolve superclass of Lblah/blah/Utility$1; (353)
W/dalvikvm(2459): Link of class 'Lblah/blah/Utility$1;' failed
E/dalvikvm(2459): Could not find class 'blah.blah.Utility$1', referenced from method blah.blah.Utility.initCaches
W/dalvikvm(2459): VFY: unable to resolve new-instance 559 (Lblah/blah/Utility$1;) in Lblah/blah/Utility;
D/dalvikvm(2459): VFY: replacing opcode 0x22 at 0x000d
D/dalvikvm(2459): VFY: dead code …
Run Code Online (Sandbox Code Playgroud)

android android-2.3-gingerbread android-lru-cache android-support-library

5
推荐指数
1
解决办法
5833
查看次数

Android LRUCache检索

我在Android中实现了一个存储对象的标准LRUCache.每个键都是与存储的Object关联的唯一ObjectId.我的问题是从缓存中检索Object的唯一方法是ObjectId(没有迭代器).实现getAll()方法的最佳方法是什么?另一种选择是将所有ObjectIds存储在某个列表的列表中,因此我可以迭代列表并获取所有对象 - 但是保存所有ObjectIds的最佳方法是什么?

谢谢!

android caching iterator lru android-lru-cache

5
推荐指数
3
解决办法
2032
查看次数

在Android中使用LruCache的NoSuchMethodError

我使用从Android中的LruCache继承的自定义类时出错.它应该下载图像并缓存它们; 昨天,它正在运作,但今天早上我遇到了这个问题.

这是该类的代码:

public class LruMemoryCache extends LruCache<String, Bitmap> {
    private final Context context;
    private static LruMemoryCache instance;

    private LruMemoryCache(Context context) {
//      super(1024 * 1024 * (((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass()) / 8);
        super(5 * 1024 * 1024);
        this.context = context;
    }

    public static synchronized LruMemoryCache getInstance(Context context) {
        if (instance == null) {
            instance = new LruMemoryCache(context);

        }
        return instance;
    }

    @Override
    protected int sizeOf(String key, Bitmap value) {
        return value.getByteCount();
    }

    public void loadBitmap(String url, ImageView imageView) {
        final String …
Run Code Online (Sandbox Code Playgroud)

android caching android-lru-cache

4
推荐指数
1
解决办法
1830
查看次数

如何清除机器人LRUCache

在Google Developer的API中有一个trimToSize()方法,我无法找到/使​​用它.如何清除或缩小LRU Cache的大小?

android android-lru-cache

3
推荐指数
1
解决办法
5024
查看次数

使用LruCache在内存中存储位图

我一直在尝试在我的应用程序中实现LruCache,但我很难连接点和在不同组件之间传递位图.

我想知道如何在我的应用程序中集成LruCache.我也希望了解实施LruCache的过程,以便更多细节

第一个类是AsyncTask Image Loader,第二个类是我的自定义适配器

的AsyncTask

 public class GetImagesBitmap extends AsyncTask<ImageView, Void, Bitmap>{
    InputStream inputStream;
    ImageView imageView = null;
    String path;




    @Override
    protected Bitmap doInBackground(ImageView... imageViews) {
        this.imageView = imageViews[0];
        return download_Image((String)imageView.getTag());
    }

    @Override
    protected void onPostExecute(Bitmap result) {

        imageView.setImageBitmap(result);
    }

    private Bitmap download_Image(String url) {


        final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse httpResponse = client.execute(httpGet);
            final int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                Log.w("ImageDownloader", "Error " + statusCode
                        + " while …
Run Code Online (Sandbox Code Playgroud)

android memory-management android-lru-cache

1
推荐指数
1
解决办法
6515
查看次数