在实际开发中,很多时候我们都需要在子线程里面进行UI更新操作,可Android是不支持在子线程中进行UI操作的,因此提供了一套异步消息处理机制。
Android异步消息处理机制主要由四部分组成:Message、Handler、MessageQueue、Looper。
1.Message:
Message是线程中传递的消息,可以携带少量信息,用于线程间数据的交换。其中Message可以使用what字段携带命令数据,arg1和arg2携带整型数据,obj字段携带一个Object对象。
2.Handler:
主要用于发送消息和处理消息 ,发送消息调用的是Handler的sendMessage()方法,发出后的消息经过系列处理后会传入到Handler的handleMessage()方法中。
3.MessageQueue:
这部分用于存放通过Handler发送的Message,这部分Message会一直存在MessageQueue之中,等待被处理。每个线程只有一个MessageQueue。
4.Looper:
每一个线程中只会有一个Looper对象,调用Looper对象的loop()方法之后,会进入到一个无限循环当中,每当发现MessageQueue中存在Message,就将它取出,传递到Handler的handleMessage()方法中去。
异步消息处理的流程:
首先在主线程中创建出一个Handler对象,并重写它的handleMessage()方法,若要进行UI操作,即可在这个方法中添加UI操作的逻辑,接着在子线程中创建一个Message对象,并通过Handler的sendMessage()方法将Message发送出去,接着Message对象会被添加到MessageQueue中等待处理,Looper会一直从MessageQueue中取出待处理的Message并将它传递到主线程的Handler的handleMessage()方法中,这样就完成了UI更新操作。
为了更方便的进行子线程的UI操作,Android还提供了很多好用的工具,比如AsyncTask,其原理也是异步消息处理机制,只不过Android进行了封装。
AsyncTask用法:
AsyncTask是一个抽象类,想要使用必须创建一个子类去继承它,在继承时可以为AsyncTask类指定3个参数:
1.Params:在执行AsyncTask时需要 传入的参数,可用于在后台任务中使用
2.Progress:后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为进度单位。
3.Result:当任务执行完毕后,如果需要对结果进行访问,则使用这里指定的泛型作为返回值返回。
创建出AsyncTask的子类后还需重写4个方法:
1.onPreExecute():这个方法在后台任务开始执行前调用,进行一些界面化的操作,比如显示一个进度条对话框。
2.doInBackground():这个方法中的操作都会在子线程进行,因此一般会在这个方法中进行一些耗时操作,任务一旦完成就会return会AsyncTask的第三个泛型参数。这个方法不可以进行UI操作,若要更新UI元素,比如说反馈当前任务的执行进度可以调用publishProgress(Progress…)方法。
3.onProgressUpdate(Progress…):当调用了publishProgress(Progress…)方法后,onProgressUpdate(Progress…)方法很快会被调用 ,携带的参数是从后台任务中传递过来的,可以在这个方法中进行UI操作。
4.onPostExecute(Result):后台任务执行完毕后会通过return返回,这个方法就会被调用,返回的数据会传入到这个方法中,可以在这里进行UI操作,比如进度对话框的关闭等。
启动任务时只需添加:new 子类名称.execute();