Android 图片的异步加载

本文介绍如何利用SoftReference实现图片缓存,包括缓存机制、异步加载流程及实例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SoftReference

SoftReference<Object> srf = new SoftReference<Object>(new Object());
//虚拟内存不足时,会回收对象
//需要获取对象时可以调用get()方法,如:
Object obj = srf.get();//如果已经被回收,为null

希望被回收,但是也想引用它

SoftReference无法阻止对象被垃圾回收器回收

图片异步加载过程

Created with Raphaël 2.1.0获取图片URL是否在缓存中?访问缓存得到图片对象显示图片访问网络yesno

以URL作为key,以图片作为value保存图片—缓存

异步加载的实现

1、异步加载图片类

public class AsyncImageLoader {
    //图片缓存对象
    //key是图片URL,值是SoftReference对象(指向Drawble)
    private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
    //实现图片的异步加载
    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(){
            @Override
            public void handleMessage(Message msg) {
                callback.imageLoaded((Drawable) msg.obj);//加载图片
            }
        };
        //新开辟一个线程,该线程用于进行图片的下载
        new Thread(){
            public void run() {
                Drawable drawable=loadImageFromUrl(imageUrl);//加载图片
                imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));//放入
                Message message = handler.obtainMessage(0, drawable);//
                handler.sendMessage(message);//发送message,用于通知接收方进行显示
            };
        }.start();
        return null;
    }
    //该方法用于根据图片的URL,从网络上下载图片
    protected Drawable loadImageFromUrl(String imageUrl) {
        try {
            //根据图片的URL,下载图片,并生成一个Drawable对象
            return Drawable.createFromStream(new URL(imageUrl).openStream(), "src");//从inputstream创建drawable;"src"用于调试的,暂时没什么用
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    //回调接口
    public interface ImageCallback{
        public void imageLoaded(Drawable imageDrawable);
    }
}

2、回调接口

public class CallbackImpl implements AsyncImageLoader.ImageCallback{
    private ImageView imageView ;

    public CallbackImpl(ImageView imageView) {
        super();
        this.imageView = imageView;
    }

    @Override
    public void imageLoaded(Drawable imageDrawable) {
        imageView.setImageDrawable(imageDrawable);
    }

}

3、使用

public class MainActivity extends Activity {

    private AsyncImageLoader loader = new AsyncImageLoader();

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        loadImage("http://www.android.com/images/icon-partners.png", R.id.imageView01);
        loadImage("http://www.android.com/images/icon-dev.png", R.id.imageView02);
        loadImage("http://www.android.com/images/icon-market.png", R.id.imageView03);
    }

    //url:下载图片的URL
    //id:ImageView控件的ID
    private void loadImage(final String url, final int id) {
        // 如果缓存过就会从缓存中取出图像,ImageCallback接口中方法也不会被执行
        ImageView imageView = (ImageView)findViewById(id);
        CallbackImpl callbackImpl = new CallbackImpl(imageView);
        Drawable cacheImage = 
            loader.loadDrawable(url, callbackImpl);
        if (cacheImage != null) {
            imageView.setImageDrawable(cacheImage);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值