ANDROID_MARS学习笔记_S04_009_用java.lang.ref.SoftReference作缓存,android.os.Handler和new Thread异步加载略图片

一、简介

二、代码流程

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 }

 

原文地址:https://www.cnblogs.com/shamgod/p/5207086.html