Handler消息传递机制

在做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);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值