一、简介
二、代码流程
1.private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();来起到缓存图片的作用
2.每当要访问图片,先在map找,找不到则new Thread().start(),访问网络得到图片,再传给handler,
Message message = handler.obtainMessage(0, drawable);
handler.sendMessage(message);
3.handler若收到message 就产生回调,没轩imageView的图片信息callback.imageLoaded((Drawable) msg.obj);
三、代码
1.xml
(1)activity_main.xml
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 > 7 <TextView 8 android:layout_width="fill_parent" 9 android:layout_height="wrap_content" 10 android:text="@string/hello" 11 /> 12 <ImageView 13 android:id="@+id/imageView01" 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content" 16 android:src="@drawable/icon" 17 /> 18 <ImageView 19 android:id="@+id/imageView02" 20 android:layout_width="wrap_content" 21 android:layout_height="wrap_content" 22 android:src="@drawable/icon" 23 /> 24 <ImageView 25 android:id="@+id/imageView03" 26 android:layout_width="wrap_content" 27 android:layout_height="wrap_content" 28 android:src="@drawable/icon" 29 /> 30 </LinearLayout>
(2)AndroidManifest.xml
1 <uses-permission android:name="android.permission.INTERNET" /> 2 <uses-permission android:name="android.permission.READ_CONTACTS" />
2.java
(1)MainActivity.java
1 import android.app.Activity; 2 import android.graphics.drawable.Drawable; 3 import android.os.Bundle; 4 import android.widget.ImageView; 5 6 public class MainActivity extends Activity { 7 /** Called when the activity is first created. */ 8 private AsyncImageLoader loader = new AsyncImageLoader(); 9 @Override 10 public void onCreate(Bundle savedInstanceState) { 11 super.onCreate(savedInstanceState); 12 setContentView(R.layout.main); 13 loadImage("http://www.android.com/images/icon-partners.png", R.id.imageView01); 14 loadImage("http://www.android.com/images/icon-dev.png", R.id.imageView02); 15 loadImage("http://www.android.com/images/icon-market.png", R.id.imageView03); 16 } 17 //url:下载图片的URL 18 //id:ImageView控件的ID 19 private void loadImage(final String url, final int id) { 20 // 如果缓存过就会从缓存中取出图像,ImageCallback接口中方法也不会被执行 21 ImageView imageView = (ImageView)findViewById(id); 22 //把imageVieww传给CallbackImpl,回调时就可以设置图片 23 CallbackImpl callbackImpl = new CallbackImpl(imageView); 24 Drawable cacheImage = 25 loader.loadDrawable(url, callbackImpl); 26 if (cacheImage != null) { 27 imageView.setImageDrawable(cacheImage); 28 } 29 } 30 }
(2)AsyncImageLoader.java
1 import java.lang.ref.SoftReference; 2 import java.net.URL; 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import android.graphics.drawable.Drawable; 7 import android.os.Handler; 8 import android.os.Message; 9 10 //该类的主要作用是实现图片的异步加载 11 public class AsyncImageLoader { 12 //图片缓存对象 13 //键是图片的URL,值是一个SoftReference对象,该对象指向一个Drawable对象 14 //这样并不影响image被garbage collecter回收 15 private Map<String, SoftReference<Drawable>> imageCache = 16 new HashMap<String, SoftReference<Drawable>>(); 17 18 //实现图片的异步加载 19 public Drawable loadDrawable(final String imageUrl,final ImageCallback callback){ 20 //查询缓存,查看当前需要下载的图片是否已经存在于缓存当中 21 if(imageCache.containsKey(imageUrl)){ 22 SoftReference<Drawable> softReference=imageCache.get(imageUrl); 23 if(softReference.get() != null){//如果为null,则说明被垃圾回收器回收了 24 return softReference.get(); 25 } 26 } 27 28 //Handler和UI是同一线程的 29 final Handler handler=new Handler(){ 30 @Override 31 public void handleMessage(Message msg) { 32 //msg.obj是handler.obtainMessage(0, drawable);传过来的 33 callback.imageLoaded((Drawable) msg.obj); 34 } 35 }; 36 37 //如果缓存没有,则新开辟一个线程,该线程用于进行图片的下载 38 //每下载一个图片,都 会开辟一个新线程,和UI不是同一线程的 39 new Thread(){ 40 public void run() { 41 Drawable drawable=loadImageFromUrl(imageUrl); 42 //把图片加到map中,以缓存图片,则下次访问不用访问网络 43 imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); 44 Message message = handler.obtainMessage(0, drawable); 45 handler.sendMessage(message); 46 }; 47 }.start(); 48 return null;//这里不能return drawable,因为它是在另一个线程,此时drawable可能还没值 49 } 50 //该方法用于根据图片的URL,从网络上下载图片 51 protected Drawable loadImageFromUrl(String imageUrl) { 52 try { 53 //根据图片的URL,下载图片,并生成一个Drawable对象 54 return Drawable.createFromStream(new URL(imageUrl).openStream(), "src"); 55 } catch (Exception e) { 56 throw new RuntimeException(e); 57 } 58 } 59 60 //回调接口 61 public interface ImageCallback{ 62 public void imageLoaded(Drawable imageDrawable); 63 } 64 }
(3)CallbackImpl.java
1 import android.graphics.drawable.Drawable; 2 import android.widget.ImageView; 3 4 public class CallbackImpl implements AsyncImageLoader.ImageCallback{ 5 private ImageView imageView ; 6 7 public CallbackImpl(ImageView imageView) { 8 super(); 9 this.imageView = imageView; 10 } 11 12 @Override 13 public void imageLoaded(Drawable imageDrawable) { 14 imageView.setImageDrawable(imageDrawable); 15 } 16 17 }