异步消息机制
- Android中是不允许子线程中对UI进行操作的,为此,它提供了一种异步消息
- 处理机制,完美了解决了在子线程中更新UI的问题。
`/**
- 主线程更新UI
*/
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 0://逻辑,进行UI操作 break; }
}
};
/**- 子线程更新数据
*/
private void update(){new Thread(new Runnable() {
@Override
public void run() {Message message = new Message(); message.what = 0; handler.sendMessage(message);//将message数据发送出去 }
}).start();
}`
Android中的异步消息处理机制主要由四部分组成,Message,Handler,MessageQueue和Looper,
Message 是在线程之间传递消息,他可以在内部携带少量的信息,用于在不同线程之间交换数据,Message 的what, 此外还有arg1,arg2,携带一些整形数据,obj携带Object对象
Handler 处理者的意思,它主要是用于发送和处理消息,发送消息一般用handler.sendMessage()方法,而发出的消息经过一些辗转之后会回到Handler的handerMessage()方法中。
MessageQueue 消息队列,它用于存放handler发送的消息。这部分消息会一直存放在消息队列中, 等待被处理,每个线程只有一个MessageQueue对象。
Looper 是每个线程中的MessageQueue的管家,调用Looper的loop()方法之后,就会进入到无限循环之中,每当发现MessageQueue中存在一条数据,就将它取出,并发送到handleMessage()之中。
- 一条message经过这样的流程辗转调用之后,就从子线程回到了主线程,并在主线程中更新UI。
使用AsyncTask
- 为了更方便的更新UI,android提供了一些好的工具,AsyncTask就是其中之一。
- 它的背后实现原理也是通过异步消息处理机制来完成的。
- 只是android做了很好的封装。
- 使用方法
- 创建一个子类继承自AsyncTask,并指定三个泛型参数,这三个泛型参数的用途:
- Params 在执行AsyncTask是需要传入的参数,可用于在后台任务中使用。
- Progress 后台任务执行时,如果需要在界面上显示当前的进度,则使用这里的泛型指定为进度单位。
- Result 当任务执行完毕后,如果需要对结果进行返回,则是这里指定的泛型作为返回值类型。
- 简单的自定义AsyncTask 就可以写成如下。
`class DownloadTask extends AsyncTask < Void,Integer,Boolean> { }
void 表示在执行AsyncTask任务的时候,不需要传递参数给后台任务。
- Integer 表示整形数据来作为进度显示单位
- Boolean 表示使用布尔类型数据来反馈执行的结果
public class MyAsyncTask extends AsyncTask <Void,Integer,Boolean> {
@Override
protected void onPreExecute() {
super.onPreExecute();
//后台任务开始执行前调用,用于一些界面上的初始化操作。 列如显示一个对话框
}
@Override
protected Boolean doInBackground(Void... params) {
//这个方法的所有代码都将在子线程进行,我们应该在这里处理耗时的任务,
// 任务一旦完成就可以通过return将任务的执行结果返回
//如果第三个参数指定为Void,则可以不回值。
//这个方法中是不能进行UI操作的,如果要更新界面可以将数据传入方法publishProgress()方法中
//列如这里将更新的数据5传递给主线程
publishProgress(Integer.valueOf(5));
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
//在后台调用 publishProgress()方法后,这个方法就会被调用,返回的数据将作为参数传递进来,
//可以在这里进行UI操作、数据的更新。
}
@Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
//当后台任务执行完毕后,并通过return语句将结果返回时,这个方法将被调用。
//后台运行的结果返回值,将通过这个参数传递进来,可以利用返回的数据进行UI操作,
// 比如提醒任务结束,关闭对话框,关闭进度条
}
}
//想要启动这个任务,只需要编写一下代码:
new MyAsyncTask().execute();