图片的异步加载及缓存

      当我们需要从网络加载图片时,最好使用异步加载的方法,新开一个线程,在此线程中执行加载图片的操作,以避免阻塞UI线程的情况的发生。可以使用继承Thread类或者实现Runnable接口的方式,也可以利用Android中的AsyncTask来实现。当然,很多时候我们会对同一张图片显示多次,如果每一次都重新从网络加载的话,必将耗费更多的时间和网络流量,也会占用更多的内存空间,所以我们可以使用缓存的方法,每一次要使用图片时都先从缓存中查找,如果有就直接拿来使用,没有的话就从网络加载,然后再放入缓存中,那么下一次就可以从缓存中找到了。

       此处还使用到了JAVA中的SoftReference类,即软引用,软引用是主要用于内存敏感的高速缓存。在jvm报告内存不足之前会清除所有的软引用,这样以来gc就有可能收集软可及的对象,可能解决内存吃紧问题,避免内存溢出。什么时候会被收集取决于gc的算法和gc运行时可用内存的大小。被 Soft Reference 指到的对象,即使没有任何 Direct

Reference,也不会被清除。一直要到 JVM 内存不足且 没有 Direct Reference 时才会清除,SoftReference 是用来设计 object-cache 之用的。如此一来 SoftReference 不但可以把对象 cache 起来,也不会造成内存不足的错误 (OutOfMemoryError)。

代码如下:

package com.buaa.async;

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 AsyncHandler {

	private SoftReference<Drawable> softReference;
	private Map<String, SoftReference<Drawable>> imagesCache = new HashMap<String, SoftReference<Drawable>>();

	public Drawable loadDrawable(final String url, final CallbackImp callbackImp) {
			// 一开始同时启动3个线程加载图片,Map中还没放进键url,所以任何一个线程都不会找到缓存,都会在网络加载一次图片。
		// 当先完成一个线程之后,再启动别的线程的话,就会去到缓存找到图片对象了。
		if (imagesCache.containsKey(url)) {
			System.out.println("有缓存");
			softReference = imagesCache.get(url);
			if (softReference.get() != null) {
				return softReference.get();

			}

		}

		final Handler handler = new Handler() {

			@Override
			public void handleMessage(Message msg) {
				// TODO Auto-generated method stub
				super.handleMessage(msg);
				System.out.println("没缓存");
				callbackImp.imageLoader((Drawable) msg.obj);
			}

		};
		new Thread() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				super.run();
				try {
					Drawable drawable = Drawable.createFromStream(
							new URL(url).openStream(), "src");
					imagesCache.put(url, new SoftReference<Drawable>(drawable));
					System.out.println("加入缓存中");
					Message message = handler.obtainMessage(0, drawable);
					handler.sendMessage(message);

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}

		}.start();
		return null;

	}

	public interface ImageCallback {
		public void imageLoader(Drawable drawable);
	}
}

 

package com.buaa.async;

import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class Async extends Activity {
	private String url;
	Button button1, button2, button3;
	private AsyncHandler handler = new AsyncHandler();
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		button1 = (Button) findViewById(R.id.button1);
		button2 = (Button) findViewById(R.id.button2);
		button3 = (Button) findViewById(R.id.button3);
		url = "http://www.baidu.com/img/baidu_sylogo1.gif";
		button1.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				loadImage(url, R.id.image1);
			}
		});
		button2.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				loadImage(url, R.id.image2);
			}
		});
		button3.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				loadImage(url, R.id.image3);
			}
		});
	}
	private void loadImage(final String url, final int id) {
		ImageView imageView = (ImageView) findViewById(id);
		CallbackImp callbackImp = new CallbackImp(imageView);
		Drawable drawable = handler.loadDrawable(url, callbackImp);
		if (drawable != null) {
			imageView.setImageDrawable(drawable);
		}
	}

}

 

package com.buaa.async;

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

import com.buaa.async.AsyncHandler.ImageCallback;

public class CallbackImp implements ImageCallback {
	public CallbackImp(ImageView imageView) {
		super();
		this.imageView = imageView;
	}

	ImageView imageView;

	@Override
	public void imageLoader(Drawable drawable) {
		// TODO Auto-generated method stub
		imageView.setImageDrawable(drawable);
	}

}

 可以参考下面的博客:

http://blog.csdn.net/liuhe688/article/details/6532519
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值