Android异步消息处理
Android异步消息处理机制
问题来源:
Android不允许在子线程中进行UI操作,而有时需要在子线程中进行耗时操作并更行UI操作,这是使用异步消息处理机制的缘由。
场景带入:
在某个界面有个Button和TextView,想要实现点击按钮之后改变TextView中Text的内容,如果直接在子线程中进行更新的话程序会崩溃。那么就使用handler来解决。
privateHandler handler=new Handler(){
publicvoid handlerMessage(Message msg){
switch(msg.what){
caseUPDATE_TEXT: //在这里进行UI操作
text.setText("I can!");
break;
default:
break;
}
}
};
new Thread(new Runnable(){
publicvoid run(){
Messagemessage=new Message(); //new一个message对象
message.what=UPDATE_TEXT;//设置要发送的message内容
handler.sendMessage(message);//发送消息
}
});
详解异步消息处理机制
异步消息处理由四个部分组成:
Message、Handler、MessageQueue、Looper
Message: 用于在线程之间传递消息,在不同线程之间交换消息。主要字段有message(用于传递的消息)、arg1.arg2(可传递整型数据)、obj(可传递对象)。
Handler: 用于处理消息。发送消息采用sendMessage(),处理消息用handleMessage()。
MessageQueue: 每个线程都会有一个MessageQueue,经过Handler发送的消息都会存放在这个queue中,等待被处理。
Looper: 每个线程中都只有一个Looper对象,用于管理MessageQueue。当发现MessageQueue中有message时,它将会把它取出来然后交给Handler的handleMessage()处理。
流程:
会在主线程创建一个Handle对象,然后重写handleMessage()方法。当子线程中需要进行UI的更新时会创建一个Message对象,然后使用sendMessage()方法进行发送,消息进去MessageQueue中,与此同时Looper会不断的从MessageQueue中查看是否有消息,一旦发现会将消息传递给handlerMessage(),由其进行处理。(注:UI更新的操作仍然是在主线程完成的)
AsyncTask
AsyncTask是基于异步消息处理机制的从子线程转回主线程的一个很好的封装,是一个抽象类,需要子类去继承,它有三个参数。
class DownloadTask extendsAsyncTask{
……
}
void 代表在执行asyncTask时需要传入的参数,可用于在后台任务中使用。
Integer指定任务执行进度的单位,这里是指整型。
Boolean任务执行完毕后的结果。
Async的诀窍:(四个需要重写的方法)
由onPreExecute()做执行前的准备,doInBackground()执行具体的耗时任务(会返回一个boolean变量),然后onPostExecute()会被调用,进行UI操作,在onPostExecute()中执行一些任务的收尾工作。
最终进行execute()就可执行。
另外,
描述:message的获取方式有两种。
Message message=new Message();
或
Message message=handler.obtainMessage();
两种都会有一样的效果,区别在于:
前者是创建一个新的message对象,后者是从MessagePool拿的,省去了创建对象申请内存。