AsyncTask和Handler都是为了不阻塞主线程而执行异步操作的类。
正式开始讨论Handler和AsyncTask之前,有几个Android的规则要强调一次:
1.只能在UI线程中访问界面;
2.UI线程被阻塞(大概5秒钟)后会导致ANR(Application Not Responding)错误。
主要接收子线程发送的数据,然后用此数据配合主线程更新UI
简单说一下Handler机制,这涉及到Handler、Looper和HandlerThread
Looper轮询器:Looper中带有一个MessageQueue(消息队列),Looper负责轮询此消息队列,将Message(消息)取出后交由Handler来处理。
HandlerThread消息循环线程:即Handler执行的线程,此线程大部分时间都在运行Looper.loop()方法,即消息轮询方法;它会通过getLooper方法返回一个Looper对象,Handler需要使用此对象作为参数创建对象。
Handler处理者:负责接收消息、发送消息和处理消息(handleMessage方法),我们需要重载handleMessage方法来处理各种消息。
Handler的一些方法:
post(Runnable)
postAtTime(Runnable,long)
postDelayed(Runnable,long)
sendEmptyMessage(int)
sendMessage(Message)
sendMessageAtTime(Message,long)
sendMessageDelayed(Message,long)
以上post类方法允许你排列一个Runnable对象到主线程队列中,
sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.
AsyncTask是一个辅助类,就是为了将Handler、Thread等封装为一个异步执行框架,方便调用。主要目的是为了“在其他线程中执行一个耗时操作,并随时报告执行进度给UI线程,执行完成后将结果报告给UI线程”。
它直接继承Object,为我们体用了三个泛型并重载了几个方法
三种泛型:
Params 启动任务执行的输入参数,比如HTTP请求的URL。
Progress 后台任务执行的进度。
Result 后台执行任务最终返回的结果,比如String。
当一个异步任务被执行的时候,需要经历四步:
onPreExecute():-----在UI线程中执行,它会在异步任务开始前执行,一般用来设置任务参数;
doInBackground(): ----接收任务参数,执行异步任务,返回结果传给第四步;执行途中,它还可以调用publishProgress方法来通知UI线程当前执行的进度; (只有它在子线程中执行,其他方法都在UI线程中执行)
onProgressUpdate(): ----当publishProgress被调用后,刷新任务进度。
onPostExecute():----当后台的异步任务完成后,它会在UI线程中被调用,并获取异步任务执行完成的结果。
有必要的话你还得重写以下这三个方法,但不是必须的:
onProgressUpdate(Progress…) -----在UI线程中执行,刷新任务进度。
onCancelled() ------用户调用取消时,要做的操作
使用AsyncTask类,以下是几条必须遵守的准则:
§ Task的实例必须在UI thread中创建;
§ execute方法必须在UI thread中调用;
§ 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法;
§ 该task只能被执行一次,否则多次调用时将会出现异常;
封装一个AsyncTask进行图片加载示例:
public class NetCacheUtils {
private static final String TAG = "NetCacheUtils";
private ImageView imageView;
public void getBitmapFromNet(ImageView imageView, String url) {
//2.执行 :异步加载类对象.excute(Params... params);
//异步下载图片
new BitmapTask().execute(imageView, url);
}
/**
* 1.自定义异步加载类
* @Params Params:输入参数。对应的是调用自定义的AsyncTask的类中调用excute()方法中传递的参数。如果不需要传递参数,则直接设为Void即可。
* @Params Progress:后台任务子线程执行的百分比
* @Params Result:后台执行任务最终返回结果。和doInBackground()方法的返回值类型保持一致。
*/
class BitmapTask extends AsyncTask