• 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 }

     

  • 相关阅读:
    排序算法之冒泡排序的思想以及Java实现
    排序算法之希尔排序的思想以及Java实现
    c# npoi分批往excel追加数据
    c# Timer按月执行任务
    windows服务+定时任务(quartz.net)+nancy
    c# linq分组 lambda分组
    批量插入sql技巧
    解决windows server 2008R2自动关机
    c# DataGridView在使用DataSource时,只显示指定的列或禁止自动生成列
    c# mongodb时间类型字段保存时相差八个小时解决办法
  • 原文地址:https://www.cnblogs.com/shamgod/p/5207086.html
Copyright © 2020-2023  润新知