我一直在努力学习有关Android开发的知识,特别是性能方面的知识,因为如今Play商店中的许多应用程序都很卡顿。我已经找到了/被引导阅读了许多文章/视频。
其中一篇关于图像缓存的具体文章链接为:http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html。
作者提供的代码链接为:http://code.google.com/p/android-imagedownloader/source/browse/trunk/src/com/example/android/imagedownloader/ImageDownloader.java。
谷歌似乎采用了其中的一个版本,并将其放入他们的示例类中:http://developer.android.com/resources/samples/XmlAdapters/src/com/example/android/xmladapters/ImageDownloader.html。
总的来说,它是很稳定的,除了我认为缓存中存在的一个缺陷。它使用了软缓存/硬缓存,将东西放入/从硬缓存中获取,因为Android系统经常重置软缓存。
然而,查看代码后,人们开始怀疑每次实例化父类时硬缓存是否会被意外重置。
首先是软缓存:
现在看一下硬缓存:
硬缓存不是静态的,而软缓存是静态的。因此,硬缓存实例及其项目随类实例的生命周期而清除。我认为这是正确的原因是,我注意到我的应用程序带有ListView/ImageView,在每次下载并永远不会缓存它时。尽管所有操作都是异步完成的,但仍然每次都访问网络。我通过在打击网络的方法中放置Log.d()语句并查看何时/多久调用来验证了这一点。添加static关键字解决了该问题,使我的应用程序性能更好。我不确定为什么会这样,因为我的适配器中只有一个ImageDownloader类的实例,如示例所示:
其中一篇关于图像缓存的具体文章链接为:http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html。
作者提供的代码链接为:http://code.google.com/p/android-imagedownloader/source/browse/trunk/src/com/example/android/imagedownloader/ImageDownloader.java。
谷歌似乎采用了其中的一个版本,并将其放入他们的示例类中:http://developer.android.com/resources/samples/XmlAdapters/src/com/example/android/xmladapters/ImageDownloader.html。
总的来说,它是很稳定的,除了我认为缓存中存在的一个缺陷。它使用了软缓存/硬缓存,将东西放入/从硬缓存中获取,因为Android系统经常重置软缓存。
然而,查看代码后,人们开始怀疑每次实例化父类时硬缓存是否会被意外重置。
首先是软缓存:
// Soft cache for bitmaps kicked out of hard cache
private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache =
new ConcurrentHashMap<String, SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2);
现在看一下硬缓存:
// Hard cache, with a fixed maximum capacity and a life duration
private final HashMap<String, Bitmap> sHardBitmapCache =
new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY / 2, 0.75f, true) {
@Override
protected boolean removeEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) {
if (size() > HARD_CACHE_CAPACITY) {
// Entries push-out of hard reference cache are transferred to soft reference cache
sSoftBitmapCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue()));
return true;
} else
return false;
}
};
硬缓存不是静态的,而软缓存是静态的。因此,硬缓存实例及其项目随类实例的生命周期而清除。我认为这是正确的原因是,我注意到我的应用程序带有ListView/ImageView,在每次下载并永远不会缓存它时。尽管所有操作都是异步完成的,但仍然每次都访问网络。我通过在打击网络的方法中放置Log.d()语句并查看何时/多久调用来验证了这一点。添加static关键字解决了该问题,使我的应用程序性能更好。我不确定为什么会这样,因为我的适配器中只有一个ImageDownloader类的实例,如示例所示:
private final ImageDownloader imageDownloader = new ImageDownloader();
问题
所有这些说法中,还有其他人经历过这种情况吗?或者我在某种程度上是疯了/错了。虽然我不是Java/Android/JVM/Dalvik/WeakReference/SoftReference专家,但感觉有些不对劲。我不知道为什么sHardBitmapCache
没有被设置为静态的,但当我进行更改后,我的应用程序停止频繁访问Web(节省了数据成本/电池消耗/提高了性能)。