AsyncTask
AsyncTask 能够适当的,简单的用于UI线程,我们可以很方便的去使用,不用自己去开启线程。
AsyncTask运行机制是这样的:所有的任务都会在后台线程上运行,最后直接在UI线程上发布。继承AsnycTask需要至少覆盖 doInBackgroud(Params…)方法,一般也会去覆盖 onPostExecute(Object result)方法。这里的2个泛型参数 Params 和 result 一个视启动程序执行的输入参数,一个是后台计算的结果类型,异步任务还有另外一个泛型参数Prosgress 用来记录后台任务的执行百分比。
private class MyTask extends AsyncTask<Params,Progress,Result>{...}
当然这3个参数如果不想用都可以设置为Void
一个异步任务的执行分4步
(1) onPreExecute(),在UI线程上调用任务后立即执行,通常用于设置任务,例如在界面显示一个进度条
(2)doInBackground(Params…) onPreExecute()执行完成后立即调用,用于处理耗时操作。异步任务的参数Params也是被传到这里,在执行的过程中可以调用publishProgress(Progress…) 来更新任务进度。
(3)onProgressUpdate(Progress…) 调用publishProgress(Progress…) 后调用,会去调用UI线程。执行时间不确定。典型的运用是显示后台执行进度的进度条动画
(4)onPostExecute(Result) 但后台doInBackground(Params…) 结束后调用,回去调用UI 线程,处理后台返回的结果
AsyncTask 注意事项
- AsyncTask类必须在UI线程中被加载
- 异步任务的实例必须在UI线程中被创建
- execute(Params) 方法也就是异步任务开始执行的方法,必须在UI线程中被调用
- AsyncTask类必须在UI线程中被加载
- 一个异步任务只能执行一次(如果执行第二次将会抛出异常)
简单的说就是 AsyncTask必须在UI Thread里面玩,一个AsyncTask只能用一次,不能重复利用。这里需要注意一点AsyncTask既然只能只能使用一次那么肯定会多次创建,所以AsyncTask会运行在后台线程池中,至于线程池Android如何管理大家有兴趣可以去研究下
下面来看一个很简单的例子
利用AsyncTask实现多线程下载图片
先实现下载的异步任务
由于图片比较耗内存这里采用了 弱引用的方式来保存ImageView对象class BitmapDownLoadTask extends AsyncTask<String,Void,Bitmap>{ //图片的地址 private String url; //使用WeakReference解决内存问题 private final WeakReference<ImageView> imageViewReference; public BitmapDownLoadTask(ImageView imageView){ imageViewReference = new WeakReference<ImageView>(imageView); } @override protected Bitmap doInBackgroud(String... params){ //下载图片的方法 return downloadBitmap(params[0]); } //下载完后执行 @override protected void onPostExecute(Bitmap bitmap){ //判断是否取消 if(isCancelled()){ bitmap = null; } //判断WeakReference不为null if(imageViewReference != null){ //获取头像 ImageView imageView = imageViewReference.get(); //判断imageView 不为空 if(imageView != null){ //设置图片 imageView.setImageBitmap(bitmap ); } } } }
downloadBitmap(url)方法 为下载图片的方法这里没有具体去实现。调用的方法也很简单
//url 图片链接
public void downloadImage(String url,ImageView imageView){
//新建下载任务
BitmapDownLoadTask bitmapTask = new BitmapDownLoadTask(imageView);
bitmapTask.execute(url);
}
这样就可以实现图片的异步下载了。