Android中图片的异步加载
转:
1、 为什么要异步加载图片
下载图片比较费时,先显示文字部分,让加载图片的过程在后台,以提升用户体验
2、 SoftReference的作用
栈内存—引用
堆内存—对象
Eg:
Object obj = new Object();
Obj = null;
当垃圾收集器启动时,会回收对象;
当一个对象没有任何引用指向,就会被回收。
SoftReference<Object>sr = new SoftReference<Object>(new Obnject());
引用是软引用,当垃圾回收器启动时,系统会判断内存是否充足,内存不足时,即使对象有引用指向,也会被回收。
Object obj = sr.get();获取软引用指向的对象,当已被回收时,返回NULL。
在这里我们使用SoftReference对象来建立图片缓存
3、 异步加载图片的方法
基本流程:
A、 获取图片URL
B、 根据URL查询缓存
Eg:假如取回了20条微博,其中5条微博是同一个人发的,这样这个人的头像就要被取回5次,这是不合理的。
解决方法:把从网络上下载的图片以键值对的方式放到缓存里,键是URL,值是下载的图片,下次再去读取图片时,先看URL是否在缓存里,如果在,就不用下载了。
C、 访问缓存or访问网络
D、 得到图片对象
E、 显示图片
代码示例:
/** * 实现图片的异步加载 * @author Zhu * */ public class AsyncImageLoader { //图片缓存对象,键是URL,值是SoftReference对象,该对象指向一个Drawable对象 private Map<String,SoftReference<Drawable>> imageCache = new HashMap<String,SoftReference<Drawable>>(); /** * 实现图片的异步加载 * @param imageUrl * @return */ public Drawable loadDrawable(final String imageUrl){ //查询缓存,查看当前要下载的图片是否已经在缓存中 if(imageCache.containsKey(imageUrl)){ SoftReference<Drawable> softReference = imageCache.get(imageUrl); if(softReference.get()!=null){ return softReference.get();//还没被回收 } } final Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); //Handler是与主程序处于同一线程的,在这里可以写加载完图片的处理,显示or存储or... } }; //新开辟一个线程 new Thread(){ @Override public void run() { // TODO Auto-generated method stub super.run(); Drawable drawable = loadImageFromUrl(imageUrl); imageCache.put(imageUrl,new SoftReference<Drawable>(drawable)); Message message = handler.obtainMessage(0,drawable); handler.sendMessage(message); } }.start(); return null; } /** * 根据图片的URL从网络上下载图片 * @param imageUrl * @return */ public Drawable loadImageFromUrl(String imageUrl){ try{ //根据图片的URL,下载图片,并生成一个Drawable对象 return Drawable.createFromStream(new URL(imageUrl).openStream(), "src"); //另一种下载图片的方法: // Drawable icon; // HttpURLConnection hc=(HttpURLConnection)new URL(imageUrl).openConnection(); // icon=new Drawable(hc.getInputStream()); // hc.disconnect(); }catch (Exception e) { // TODO: handle exception throw new RuntimeException(e); } } }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。