网络图片异步加载(用到多线程(线程池),java回调机制,图片缓存,图片的动画)

本文介绍如何利用线程池、回调机制实现图片的异步加载与缓存功能,并通过渐隐动画方式展示加载完成的图片。

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

用线程池,回调,进行图片的异步加载,实现图片的缓存,并且以渐隐动画的方式显示出来

不必多说,线程池,回调,这些在java里面都算是非常重要的角色。

线程池 线程池就是管理多线程的一个东西,在多线程的操作中,如果遇到大量需要很多线程进行执行任务的时候,有的时候真正在线程里面执行任务的时间都不一定有进行线程的开启和销毁需要的时间多,这个时候使用线程池,就大大提高了处理器的吞吐能力,自然就提高了程序的性能。
       而在这里只是用到了这些东西,线程池不多说,说起来说不完,东西太多,以后有可能回再出一篇关于线程池的理解的帖子

回调 简单来说,回调就是是一种常见的设计模型,他把工作流内的某个功能,按照约定的接口暴露给外部使用者,为外部使用者提供数据,或要求外部使用者提供数据
 比如说A为一个activity,S为一个service,A请求S下载一个mp3文件,然后下载后A想打开,但是没有下载完打开肯定会出错,而A不能一直等着mp3一点点的下载,所以在A给S发送这个指令后,S开始下载,A去干其他的事情,当S下载完成后直接回调给A一个消息,A这下就知道mp3下载完成了,这个时候就可以直接打开。就是这个简单的道理,这里也不做过多的解释,之后会继续做出一边文章详解。

先来一张效果图,截图不是很好,意思到了:


这里直接上代码:

一共有3个类:
1.MainActivity.java进行图片的展示界面
2.AsyncLoad.java 进行图片的异步加载
3.SetImage.java 进行回调接口的实现,并且加入动画
名字起的比较随便··

代码注释比较详细,就不多于赘述
1.MainActivity.java
<pre name="code" class="java">public class MainActivity extends Activity {
	private String[] list = {
			"http://10.10.8.115:8080/HealthyData/images/8a94622d62965b95104cb8558ccabad8.jpg",
			"http://10.10.8.115:8080/HealthyData/images/191cd461a9120bb37b1f88dd3019613b.jpg",
			"http://10.10.8.115:8080/HealthyData/images/f6c26210fbfa76e958602264d5b0e016.jpg",
			"http://10.10.8.115:8080/HealthyData/images/a7f36e53bf308290a97c478afb446221.jpg",
			"http://10.10.8.115:8080/HealthyData/images/d4919ff7ca954a681193d8c2f696c564.jpg",
			"http://10.10.8.115:8080/HealthyData/images/b2901d3d40e2343210e32c2a17a24d4b.jpg",
			"http://10.10.8.115:8080/HealthyData/images/cbbe89dd3419dad0f6c484186f34c9a7.jpg",
			"http://10.10.8.115:8080/HealthyData/images/0faa3c63a1c1c4040ccb0b59ff2fdfde.jpg",
			"http://10.10.8.115:8080/HealthyData/images/7dca92b74a9b83ce021cfdc5fd29fc07.jpg",
			"http://10.10.8.115:8080/HealthyData/images/3cef2859c059905002eae29915be5be7.jpg",
			"http://10.10.8.115:8080/HealthyData/images/4f0952f7456ff2e545d5bee4eef0be3b.jpg",
			"http://10.10.8.115:8080/HealthyData/images/e0e14234a862c5eb24750ec71cbf0320.jpg",
			"http://10.10.8.115:8080/HealthyData/images/03ac23dd101dd18f107aae2d095b66d4.jpg",
			"http://10.10.8.115:8080/HealthyData/images/9053a81db4b4d5e9e00869df3897b75a.jpg",
			"http://10.10.8.115:8080/HealthyData/images/02829476989b75950dc58935ec2cf132.jpg",
			"http://10.10.8.115:8080/HealthyData/images/44d3d2eb56068a29dd4d2e47d1f863f0.jpg",
			"http://10.10.8.115:8080/HealthyData/images/1114565897b785a688c5e48dbbf41970.jpg",
			"http://10.10.8.115:8080/HealthyData/images/1a5687efb11ccb74e5e0e36cb95564e9.jpg",
			"http://10.10.8.115:8080/HealthyData/images/ecbc3b076f9ff3c12d1e9553a4bc3c64.jpg",
			"http://10.10.8.115:8080/HealthyData/msjimages/image_basic/msj_b282bc0649dabe89fe40230d1b89cd0e_150x150.jpg",
			"http://10.10.8.115:8080/HealthyData/msjimages/image_basic/msj_ae66c41d0d5f6c179060c3dfbdbe7ad8_150x150.jpg",
			"http://10.10.8.115:8080/HealthyData/msjimages/image_basic/msj_80a635542077dee4034ef36963bc294f_150x150.jpg",
			"http://10.10.8.115:8080/HealthyData/msjimages/image_basic/msj_3ee3f63bbcdde088b1baaa862ac922c1_150x150.jpg",
			"http://10.10.8.115:8080/HealthyData/msjimages/image_basic/msj_b7c42a1d52656b28fc99b2f327c40970_150x150.jpg",
			"http://10.10.8.115:8080/HealthyData/msjimages/image_basic/msj_9e5fac83ff569458926c0f5d4743b84c_150x150.jpg",
			"http://10.10.8.115:8080/HealthyData/msjimages/image_basic/msj_c5bfa8da120bcd1b31583d3bb178c7ac_150x150.jpg",
			"http://10.10.8.115:8080/HealthyData/msjimages/image_basic/msj_4219856824eedba5fa00b67f6bc18ef7_150x150.jpg",
			"http://10.10.8.115:8080/HealthyData/msjimages/image_basic/msj_a2fed0ed6a8da6348dde541b437cafa7_150x150.jpg",
			"http://10.10.8.115:8080/HealthyData/msjimages/image_basic/msj_45b0841f5bca5b0a0d6bf7591acbe1e0_150x150.jpg",
			"http://10.10.8.115:8080/HealthyData/msjimages/image_basic/msj_548d5c7b351efd7b2a62d435b3b36671_150x150.jpg",

	};
	private Button button;
	private GridView gridView;
	private ExecutorService pool;
	private Map<String, SoftReference<Bitmap>> iCache;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		pool = Executors.newFixedThreadPool(5);
		iCache = new HashMap<String, SoftReference<Bitmap>>();
		button = (Button) findViewById(R.id.button);
		gridView = (GridView) findViewById(R.id.grid);
		button.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				gridView.setAdapter(new Adapters(list, getApplicationContext()));
			}
		});

	}

	class Adapters extends BaseAdapter {

		private String[] list;
		private Context context;

		public Adapters(String[] list, Context context) {
			this.list = list;
			this.context = context;

		}

		@Override
		public int getCount() {
			return list.length;
		}

		@Override
		public Object getItem(int position) {
			return list[position];
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			convertView = LayoutInflater.from(context).inflate(
					R.layout.adapter, null);
			ImageView imageView = (ImageView) convertView.findViewById(R.id.iv);
			// 实例化一个实现回调接口的对象,将该对象作为参数放到回调监听中
			SetImage setImage = new SetImage(imageView);
			// 实例化一个异步加载图片类的对象
			AsyncLoad asyncLoad = new AsyncLoad(pool, iCache);
			// 在这里设置回调监听
			asyncLoad.loadDrawable(list[position], setImage);

			return convertView;
		}
	}
}
 
 
 
 
 

这里的list是我自己搭建服务器里面的图片文件,这个需要的朋友得自己去找一些可用的图片资源链接。

2.AsyncLoad.java 

//该类的主要作用是实现图片的异步加载
public class AsyncLoad {
	// 图片缓存对象
	// 键是图片的URL,值是一个SoftReference对象,该对象指向一个Bitmap对象
	private Map<String, SoftReference<Bitmap>> imageCache;
	// 使用线程池去执行任务
	private ExecutorService pool;
	// 初始化线程池和缓存
	public AsyncLoad(ExecutorService pool,
			Map<String, SoftReference<Bitmap>> imageCache) {
		this.pool = pool;
		this.imageCache = imageCache;
	}
	// 实现图片的异步加载
	public void loadDrawable(final String imageUrl, final ImageCallback callback) {
		// 查询缓存,查看当前需要下载的图片是否已经存在于缓存当中
		if (imageCache.containsKey(imageUrl)) {
			SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
			if (softReference.get() != null) {
				callback.imageLoaded(softReference.get());
				return;
			}
		}
		// 缓存中没有图片,就去下载
		final Handler handler = new Handler() {
			public void handleMessage(Message msg) {
				// 图片下载好以后在这里进行回调,就会直接去调用实现该接口的对象所实现的方法
				callback.imageLoaded((Bitmap) msg.obj);
			}
		};
		// 新建图片下载任务放到线程池里面去执行
		pool.execute(new Runnable() {

			@Override
			public void run() {
				System.out.println(Thread.currentThread().getName());
				Bitmap bitmap = loadImageFromUrl(imageUrl);
				// 得到图片后放到缓存之中
				imageCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));
				Message message = handler.obtainMessage(0, bitmap);
				handler.sendMessage(message);

			}
		});
	}
	// 该方法用于根据图片的URL,从网络上下载图片
	protected Bitmap loadImageFromUrl(String imageUrl) {
		// 这里设置option是为了防止图片过大,造成内存溢出
		BitmapFactory.Options options = new Options();
		options.inJustDecodeBounds = true;
		try {
			BitmapFactory.decodeStream(new URL(imageUrl).openStream(),
					new Rect(), options);
			// 根据图片的宽进行放大倍数的计算
			int length = options.outWidth;
			double a = length / 100;
			if (a < 1) {
				a = 1;
			}
			options.inSampleSize = (int) (a + 1);
			options.inJustDecodeBounds = false;
			// 下载图片
			Bitmap bitmap = BitmapFactory.decodeStream(
					new URL(imageUrl).openStream(), new Rect(), options);
			return bitmap;
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		return null;

		// try {
		// // 根据图片的URL,下载图片,并生成一个Drawable对象
		// return Drawable.createFromStream(new URL(imageUrl).openStream(),
		// "src");
		// } catch (Exception e) {
		// throw new RuntimeException(e);
		// }
	}

	// 回调接口
	public interface ImageCallback {
		public void imageLoaded(Bitmap bitmap);
	}
}

3. SetImage.java  

/**
 * 实现回调接口
 * 
 * @author 
 * @version 1.0.0
 * @2013-4-23 下午3:30:30
 */
public class SetImage implements AsyncLoad.ImageCallback {
	private ImageView iView;
	// 这里进行要放置图片的ImageView 的初始化
	public SetImage(ImageView imageView) {
		this.iView = imageView;
	}
	// 回调方法,当方法被调用的时候,直接进行图片的加载
	@Override
	public void imageLoaded(Bitmap imageDrawable) {
		// 设置动画效果
		AnimationSet animationSet = new AnimationSet(true);
		AlphaAnimation alphaAnimation = new AlphaAnimation(0.1f, 1f);
		ScaleAnimation scaleAnimation = new ScaleAnimation(0f, 1f, 0f, 1f,
				Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
				0.5f);
		RotateAnimation rotateAnimation = new RotateAnimation(0, 360,
				Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
				0.5f);
		// 加入动画
		animationSet.setDuration(3 * 1000);
		animationSet.addAnimation(alphaAnimation);//设置渐隐
		animationSet.addAnimation(scaleAnimation);//设置伸缩
		// animationSet.addAnimation(rotateAnimation);//设置旋转
		//设置停留在动画最后的状态
		animationSet.setFillAfter(true);
//		为ImageView加载动画
		iView.startAnimation(animationSet);
		iView.setImageBitmap(imageDrawable);
		iView.setScaleType(ScaleType.FIT_XY);

	}

}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值