博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android图片异步加载的方法
阅读量:5364 次
发布时间:2019-06-15

本文共 4155 字,大约阅读时间需要 13 分钟。

    很多时候,我们在加载大图片或者需要处理较多图像数据的时候,希望显示效果能好点,不至于因为图片解码耗时产生ANR等情况,不得不说异步加载是个不错的方法。说到异步加载,避免application出现ANR情况,我们一般都是另起线程,不占用Main Thread,这样就能避免ANR情况产生。常用的异步方法有:AsyncTask,HandlerThread,Activity.runOnUIThread(Runnable)等。本文介绍的大图片异步加载使用的就是AsyncTask来实现的。

    先定义一个ImageView对象image,该对象就是我们最终要显示的图片。简化我们获取图片的过程,这里用resource id即放在drawable下的图片mActualImageId为例,当然,我们也可以从网络上下载或者设定选定SD卡中的某张图片。图片未真正解码获取之前,我们用加载图片显示mLoadingImage。

    第一步:创建AsyncTask

 

private class BitmapWorkerTask extends AsyncTask
{ private int mResId; private final WeakReference
imageViewReference; public BitmapWorkerTask(ImageView imageView) { imageViewReference = new WeakReference
(imageView); } /** * Background processing. */ @Override protected BitmapDrawable doInBackground(Integer... params) { Log.d(TAG, "doInBackground - starting work"); mResId = params[0].intValue(); Bitmap bitmap = null; BitmapDrawable drawable = null; Log.d(TAG, "doInBackground - mResId = " + mResId); if (bitmap == null) { bitmap = processBitmap(mResId); } if (bitmap != null) { // Running on Honeycomb or newer, so wrap in a standard BitmapDrawable drawable = new BitmapDrawable(mResource, bitmap); } Log.d(TAG, "doInBackground - finished work"); return drawable; } /** * Once the image is processed, associates it to the imageView */ @Override protected void onPostExecute(BitmapDrawable value) { // if cancel was called on this task or the "exit early" flag is set then we're done final ImageView imageView = getAttachedImageView(); if (value != null && imageView != null) { Log.d(TAG, "onPostExecute - setting bitmap"); if (mProgress != null) { mProgress.setVisibility(View.GONE); } setImageDrawable(imageView, value); } } private ImageView getAttachedImageView() { final ImageView imageView = imageViewReference.get(); final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); if (this == bitmapWorkerTask) { return imageView; } return null; } }

从上面代码看,processBitmap就是在做图片解码的动作,如果对resource id做解码,使用BitmapFactory.decodeResource。如果对图片文件解码,使用BitmapFactory.decodeFile。还有一种使用BitmapFactory.decodeFileDescriptor解码。结果都是返回解码后的Bitmap,创建得到drawable对象并传给主线程,在onPostExecute中用ImageView的接口函数setImageDrawable接口将最终图片显示内容显示出来。

 

第二步:创建异步drawable对象

先看我们创建的异步drawable对象是什么?

 

private static class AsyncDrawable extends BitmapDrawable {        private final WeakReference
bitmapWorkerTaskReference; public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { super(res, bitmap); bitmapWorkerTaskReference = new WeakReference
(bitmapWorkerTask); } public BitmapWorkerTask getBitmapWorkerTask() { return bitmapWorkerTaskReference.get(); } }

该类很重要的一个成员是弱引用bitmapWorkerTaskReference,在内存不足的情况下,弱引用指向的数据会被系统回收,这样就不会因系统内存不足,长时间等待而引起ANR。注意到构造函数实际上会调用super(res, bitmap),我们这个类继承自BitmapDrawable,如果撇开弱引用不管,这个类实际上就是BitmapDrawable。

 

好,铺垫了这么多,异步加载的方法下面可以展开了。

第三步:异步加载图片

 

public void loadImage(int resId, ImageView image) {		if (image == null) {			return ;		}				mActualImageId = resId;		mAsyncTask = new BitmapWorkerTask(image);		final AsyncDrawable asyncDrawable = new AsyncDrawable(mResource, mLoadingImage, mAsyncTask);		image.setImageDrawable(asyncDrawable);		mAsyncTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, mActualImageId);	}

首先,创建AsyncTask对象mAsyncTask;

 

然后,创建一个异步drawable对象asyncDrawable,调用ImageView对象image的setImageDrawable方法。到这步,我们界面上显示的暂时是一个临时的图片,如:

最后,我们启动AsyncTask去解码,并最终解码获得图片的drawable对象。使用ImageView的接口函数setImageDrawable接口将最终图片显示内容显示出来。实例如下图:

 

转载于:https://www.cnblogs.com/suncoolcat/p/3323159.html

你可能感兴趣的文章
[redis] redis
查看>>
Linux的加密认证功能以及openssl详解
查看>>
[Tools] 使用XP远程登录Win8系统
查看>>
【RL-TCPnet网络教程】第38章 TFTP简单文件传输基础知识
查看>>
HDU- 2265 Encoding The Diary
查看>>
socket基本概念
查看>>
[第三方]SCNetworkReachability 获取网络状态控件使用方法
查看>>
在Windows上使用putty连接一台Linux主机
查看>>
Socket常见错误
查看>>
百度地图2.0API和3.0API。你想要的百度地图的这都有
查看>>
专业词汇
查看>>
星期五的收获
查看>>
proxmox 去除订阅提示
查看>>
使用Html.EditorFor()为文本框加上maxlength,placeholder等属性
查看>>
[转]后缀数组求最长重复子串
查看>>
设计模式——外观模式详解
查看>>
MVC3 控件
查看>>
mysql (一)
查看>>
photoshop图层样式初识1
查看>>
【.NET】使用HtmlAgilityPack抓取网页数据
查看>>