您的位置:首页 > 移动开发 > Android开发

Handler消息传递机制

2016-01-27 09:40 375 查看
在做Android开发的过程中,不免会遇到在其他线程中需要更新UI界面的情况,然而UI界面组件只允许主线程去更新它,这时我们就可以用到handler消息机制了。

跟Handler消息机制有关的几个组件做一下介绍:

Message:handler发送和处理的消息对象,相当于一个数据模型。它可以携带一个bundle对象,还可以携带一个obj对象,还可以设置一个标志位属性message.what。

Looper:它的loop方法负责读取MessageQueue中的消息,读到之后就会把消息交给发送这条消息的handler进行处理。每个线程只有一个Looper。Looperd的构造器是私有的,不能显示调用构造器new一个Looper对象,要活的Looper的对象可以使用Looper的prepare方法获得一个单例对象。

Messagequeue:一个管理Message的消息队列,在创建Looper的时候会在Looper的构造器中去创建MessageQueue对象。

实际上在新的线程中使用handler只需要如下三步:

1、调用Looper的prepare()方法为当前线程创建Looper,在创建Looper的同时也会创建与之配套的MessageQueue。

2、创建Handler的子类实例,重写handlemessage()方法。

3、调用Looper的loop( ) 方法启动Looper,这样Looper就会不断地从MessageQueue中取出消息并发送给Handler了。一个新的线程调用了Looper.loop( )方法之后,线程就处于一个死循环当中了,如果在这个方法后面还写了代码也不会执行了,当然我们是默认不允许在loop()方法后面再写代码了。

心得:想想handler是如何通过子线程发消息,最终让主线程响应呢?这个说起来比较复杂,总的来说就是每一个handler始终依附于创建它的那个线程,它发送的消息除了调用sendMessageAtFrontOfQueue()方法之外,其他的都会进入到handler所属的那个线程持有的消息队列中去,然后Looper.loop()方法取出这条消息后,其中消息中有一个target属性,这个target其实就是这个handler自己本身,于是自然就会回调handler中实现的handlemessage()方法。

注意:在UI主线程中,系统已经初始化了一个Looper和对应的MessageQueue对象了,因此可以在主线程中直接创建handler然后使用。

下面贴一点简单的代码:

//实现的功能是在js里面调用暴露的方法,去操作主界面的标题
//首先在主界面中定义一个Handler
public class MianActivity extends Activity {
WebView webview;
Handler handler = new Handler() {
@Override
//重写处理功能逻辑的方法
public void handleMessage(android.os.Message msg) {
try {
String titlename = msg.getData().getString("titlename");
if (titlename.equals("")) {
// 传过来的字符串为空字符串使用之前保留的名称
texttitle.setText(toptitle);
} else {
// 否则设定具体的名字
texttitle.setText(titlename);
}
} catch (Exception e) {

}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
webview=(WebView)findViewById(R.id.workflow_webview);
。。。
//把对象暴露给js,初始化对象的时候把主线程中的handler传过去
webview.addJavascriptInterface(new ObjectForJavaScript(this,handler), "javaCB");
}
}

//这个是暴露给js的对象
public class ObjectForJavaScript {
Context context;
Handler handler=null;
public ObjectForJavaScript(Context context,Handler handler){
this.context=context;
this.handler=handler;
}
/**
* 设定标题
*/
@JavascriptInterface
public void settitle(String title){
Message mess=new Message();
Bundle b=new Bundle();
b.putString("titlename", title);
mess.setData(b);
handler.sendMessage(mess);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android handler 线程