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然后使用。
下面贴一点简单的代码:
跟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); } }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories