1、列表视图适配器获取列表视图条目:getView
不要每次都创建视图,如果没有才创建,只创建一次,节省内存。如果滚动页面非常庞大,每次都重新创建视图,则内存消耗太大,性能会越来越慢,直到崩溃。
2、图片的下载策略:先内存、后文件、最后网络。
3、图片下载采用异步线程,但在上下频繁滚动时,同时会大量多线程连接网络,老报连接超时异常:SocketTimeoutException
解决办法:1、加入线程管理,用线程池方面,限定最大的连接数。
2、采用“滚动时不下载的, 停止时才下载”的策略:即滚动时取消所以下载线程,滚动停止时只下载当前可视条目的图片,保证每次连接线程就那么几个。
3、还有人说用HttpClient代替HttpURLConnection,说前者更强大,这个没试过,有待研究。
4、图片以输入流InputStream的方式下载下来后,如果直接解码图片,不但消耗内存,而且如果网络的图片太大直接可能导致OOM,因此要根据实际显示的大小解码图片。
要先设置opts.inJustDecodeBounds = true;解码边界,计算出显示比例后,再设置opts.inJustDecodeBounds = false;根据实际显示的大小解码图片。这时有个问题,一个网络获取的输入流InputStream,只能被读取1次,产生矛盾:输入流只能被读取1次,但解码必须要两次。
几种处理办法:1、重新连接在获取1次,但多一次网络连接严重影响性能。网络连接是性能的瓶颈。
2、输入流InputStream保存成本地文件,通过文件可以new两次文件输入流FileInputStream:
BitmapFactory.decodeStream(new FileInputStream(filepath), null, opts);缺点也是影响性能,但比两次网络连接要好些。
3、输入流InputStream转换成字节串,通过对字节串解码。缺点是字节串在内存中,内存开销大。
5、由于列表视图会显示下载大量图片,使用完后,如果列表视图一直存在则没有释放图片内存的机会,最终导致OOM崩溃。
解决办法:下载的图片用内存缓存(硬引用LruCache、软引用SoftReference<Bitmap>),系统根据内存情况,自动释放。