在Android软件开发过程中,如果下载图片过多的话,很容易造成内存溢出( java.lang.OutOfMemoryError: bitmap size exceeds VM budget)。针对这个问题在网上收集了一些资料,Android官方已经给出了解决方法,本文阅读和使用这些资料后的简单总结。
一资料
1 官方解决方案util类
使用比较方便仅一个工具类,传入url和imageview即可。使用map缓存+软引用避免内存溢出问题,使用多线程避免滑动不流畅。
2 可运行例子 google官方blog讲解(需翻 墙)
google工程师出的一个可运行的例子,并且带有详细的讲解文档。例子演三种情况no task(不使用多线程),random(滚动ListView随机加载图片),correct(使用多线程依次加载图片)
3 Green Droid中的例子
Green Droid项目地址 其中AsyncImageView in ListView是加载图片的例子
4 android官方文档DDMS使用方法
二 ListView加载图片可能遇到的问题:
1. bitmap内存溢出,什么情况下会出现溢出?如何解决?
1.1 通过工具检测Android的内存使用情况,什么时候出现异常?
可以使用Android 提供的DDMS工具和adb shell命令行,查看Heap的使用情况。
1) 使用DDMS查看(具体使用方法可以查看资料4),打开DDMS有两种打开方式:
一 使用Eclipse DDMS视图
需要先安装Android SDK 和 Eclispe ADT插件,如果Eclipse中没有DDMS,可能是ADT版本过低,可以通过命令方式打开。
Eclipse --> Window --> Open Perspective --> DDMS
二 使用命令打开
widnows : Android SDK的文件目录/tools/ddms.exe
linux : Android SDK的文件目录/tools/ddms (shell脚本)
2) 使用adb shell 命令
adb shell
dumpsys meminfo dumpsys meminfo com.example.android.imagedownloader
dumpsys meminfo + packageName
详细使用情况可以查看
2. ListView滚动流畅,滚动起来等到图片加载完才能显示下一个item,在资料2中的例子可以看到以下效果
3 使用多线程可能出现的问题?
3.1 子线程中加载到一半,再次请求,会下载多次
解决 : 每个ImageView的Drawable自定义,并持有AsyncTask(资料1使用的方法)
3.2 快速滚动,一次加载过多
1. 不处理,每次加载都新启一个线程(后果?) (资料1和2 使用这种)
2. 使用线程池,每次仅限制5个线程加载图片(资料3使用这种)
(Tread或者AsyncTask多次execute)
3. drawSelectorOnTop 参数
bitmap缓存
https://github.com/chrisbanes/Android-BitmapMemoryCache