异步加载图片的小例子

Android开发当中,经常会碰到图片的异步加载问题(也叫延时加载,英文叫 Lazyload)。图片的读取工作是个比较耗时的工作,如果还是从互联网读取图片资源就更加耗时。如果在主线程里处理的时间过长,就会引发著名的应用程序无响应的系统提示(ANR:Application Not Responding)。

那下面我们就写一个异步加载图片的小例子,当然这只是基本例子,如果需要更加复杂的需要在此基础上继续开发!

 

程序架构:

main.xml文件:


<?
xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="异步加载图片" /> <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> <ImageView android:id="@+id/imageView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> <ImageView android:id="@+id/imageView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> </LinearLayout>

 

代码1——AsyncImageLoader.java:

package lenghan.ma;

import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
//该类的主要作用是实现图片的异步加载
public class AsyncImageLoader{ 
    //图片缓存对象
    //键是图片的URL,值是一个SoftReference对象,该对象指向一个Drawable对象
    private Map<String,SoftReference<Drawable>> imageCache=
                          new HashMap<String,SoftReference<Drawable>>();
    //实现图片的异步加载
    //imageUrl:图片的url
    //callback:内部回调方法
    public Drawable loadDrawable(final String imageUrl,final ImageCallback callback){
        //查询缓存,查看当前需要下载的图片是否已在缓存当中
        if(imageCache.containsKey(imageUrl)){
            SoftReference<Drawable> softReference=imageCache.get(imageUrl);
            if(softReference.get()!=null){
                return softReference.get();
             }
        }
        final Handler handler=new Handler(){
            public void handleMessage(Message msg) {
                //把新线程下载下载来的Drawable对象放到imageView中
                callback.ImageLoaded((Drawable)msg.obj);
            }
        };
        //新开辟一个线程,用于进行图片的下载
        new Thread(){
            public void run(){
                //下载图片
                Drawable drawable=loadImageFromUrl(imageUrl);
                //把图片放到缓存中
                imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
                //声明一个message对象
                Message message=handler.obtainMessage(0,drawable);
                //发送消息
                handler.sendMessage(message);
            };
        }.start();
        return null;
    }

    //用于根据图片的URL,从网络上下载图片
    protected Drawable loadImageFromUrl(String imageUrl) {
        try {
            //根据图片的URL,下载图片,并生成Drawable对象
            return Drawable.createFromStream(new URL(imageUrl).openStream(), "src");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    //回调方法
    public interface ImageCallback {
        public void ImageLoaded(Drawable imageDrawable);
    }
}

 代码2——CallbackImpl.java

package lenghan.ma;

import android.graphics.drawable.Drawable;
import android.widget.ImageView;

public class CallbackImpl implements AsyncImageLoader.ImageCallback{
    private ImageView imageView;
    public CallbackImpl(ImageView imageView){
        super();
        this.imageView=imageView;
    }
    public void ImageLoaded(Drawable imageDrawable) {
        imageView.setImageDrawable(imageDrawable);
    }
}

 

代码3——ImageActivity.java:

package lenghan.ma;

import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.ImageView;

public class ImageActivity extends Activity {
    private AsyncImageLoader loader=new AsyncImageLoader();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        loadImage("http://www.android.com/images/icon-partners.png",R.id.imageView1);
        loadImage("http://www.android.com/images/icon-dev.png",R.id.imageView2);
        loadImage("http://www.android.com/images/icon-market.png",R.id.imageView3);
    }    
    //用于下载图片,并把下载得到的图片放到ImageView控件中          
    //url:下载图片的URL
    //id:ImageView空间的ID 
    private void loadImage(final String url,final int id){
        //根据空间的ID得到控件
        ImageView imageView=(ImageView)findViewById(id);
        //如果图片缓存过就会从缓存中取出图片,ImageCallback接口中方法就不会被执行
        CallbackImpl callbackImpl=new CallbackImpl(imageView);
        Drawable Imagecache=loader.loadDrawable(url, callbackImpl);
        //Imagecache如果为空就说明缓存中有Drawable对象,就把Drawable对象放到ImageView中
        if(Imagecache!=null){
            imageView.setImageDrawable(Imagecache);
        }
    }
}
posted @ 2012-04-19 13:12  AZ_mxl  阅读(888)  评论(0)    收藏  举报