作为一个Android开发者,我们肯定熟悉并使用过Handler机制。最常用的使用场景是“在子线程更新ui”,实际上我们知道上面的说话是错误的。因为Android中只有主线程才能更新ui,那么当我们在子线程得到更新ui通知的时候怎么办?此刻Handler存在的意义就体现出来了。我们在子线程用handler发送一个消息通知给主线程,然后让主线程更新ui,这样问题就解决了。下面让我们看看handler怎么使用的吧!!!

<一>Handler的基本使用

public class HandlerActivity extends Activity 

    private final String TAG = "HandlerActivity.class";

    private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d(TAG,"arg1------"+msg.arg1); --- 1
Log.d(TAG,"arg2------"+msg.arg2); --- 2
Person person = (Person) msg.obj;
if (person != null ){
Log.d(TAG,"person.age------"+person.getAge()); --- 555
Log.d(TAG,"person.name------"+person.getName()); --- Liu
}
}
}; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler); new Thread(new Runnable() {
@Override
public void run() {
/**
* 传递简单Integer类型消息
*/
Message message = new Message();
message.arg1 = 1;
message.arg2 = 2; /**
* 传递复杂消息
*/
Person person = new Person();
person.setAge(555);
person.setName("Liu");
message.obj = person; mHandler.sendMessage(message);
}
}).start();
}
}

    由上可见,我们在使用handler发送消息的时候,并且可以传递一些数据信息。在传递消息的时候我们用到了Message,并通过new的方式实例化。下面让我们看一下获取Message的第二种方法。

<二>获取Message的另一种方式以及源码分析

                Message message = mHandler.obtainMessage();
message.sendToTarget();

同第一种方式相比,获取Message和发送Message的方法都不一样了。其实如果跟进源码你可以发现,这种方式其实就是把第一种方式封装了一下,跟随我看一下源码吧!!!

首先先来看一下获取Message的方法,入口是在Handler的obtainMessage方法:

    public final Message obtainMessage(){
return Message.obtain(this);
}

继续跟Message的obtain方法

   public static Message obtain(Handler h) {
Message m = obtain();
m.target = h;
return m;
}

  在这里我们看到有两步操作,一个是调用本类的obtain方法,另一个是将Handler引用赋值给Message的target对象。接下来看一下obtain方法

    public static Message obtain() {
synchronized (sPoolSync) {
if (sPool != null) {
Message m = sPool;
sPool = m.next;
m.next = null;
m.flags = 0; // clear in-use flag
sPoolSize--;
return m;
}
}
return new Message();
}

  我们看到最后实例化的方式和第一种意义,都是通过new的方法。好了!!!消息获取到了,下面看看它是怎么发送消息的吧!!!,直接看Message的sendToTarget方法。

    public void sendToTarget() {
target.sendMessage(this);
}

还记得我们之前给target赋值的是什么吗?没错,就是handler,所以第二种方式其实就是对第一种方式的封装。

<三>Handler的七种发信息的方法

  上面我们是通过Handler的sendMessage(Message msg)发送消息的,下面在来看看Handler的其他六种发送消息方式。这六种方法又分为两类:

    (一) 携带消息Message

      1> sendMessageAtTime(Message msg, long uptimeMillis)     在指定时间发送消息到队列

      2> sendMessageAtFrontOfQueue(Message msg)  立即发送Message到队列,而且是放在队列的最前面

      3> sendMessageDelayed(Message msg, long delayMillis)  延迟delayMillis时间发送消息到队列

    (二) 不携带消息Message

      4> sendEmptyMessage(int what)   发送空消息到队列

      5> sendEmptyMessageAtTime(int what, long uptimeMillis)  在指定时间发送空消息到队列

      6> sendEmptyMessageDelayed(int what, long delayMillis) 延迟delayMillis发送空消息到队列

  跟踪源码你会发现,这几个方法最终调用的都是 sendMessageAtTime,如下图:

  

最新文章

  1. Linux启动界面切换:图形界面-字符界面(转)
  2. MySQL_02之增删改查、PHP数据库操作
  3. Django 1.9 Post 时候出现 CSRF token missing or incorrect 错误
  4. ExtJS -- Grid 文本居中显示
  5. (转)函数调用方式与extern &quot;C&quot;
  6. STL学习之路
  7. JAVA中的各种 哈希码(HashCode) 与 equals方法在HIBERNATE的实际应用[转载]
  8. JAVA - hashcode与equals作用、关系
  9. 创建mysql数据库的时候指定编码
  10. 一个想法(续四):IT技术联盟创业众筹进度公示
  11. objective-c中类似ruby枚举类的实例方法
  12. Android项目实战(四十五):Zxing二维码切换横屏扫描
  13. Log4Net使用学习笔记
  14. java 原码反码及补码 总结
  15. POM、STS、IOC、DI、AOP
  16. python全栈开发day34-线程Thread
  17. rac备份及恢复的重要概念之一——Redo Threads和Streams
  18. 对spark算子aggregateByKey的理解
  19. MVC 在action拦截器中获取当前进入的控制器和aciton名
  20. Spark 实践——基于 Spark MLlib 和 YFCC 100M 数据集的景点推荐系统

热门文章

  1. 消息队列——RabbitMQ学习笔记
  2. JAVA for mac 的学习之路
  3. windows+nginx+iis+redis+Task.MainForm构建分布式架构 之 (nginx+iis构建服务集群)
  4. 在jekyll模板博客中添加网易云模块
  5. .NET跨平台之运行与Linux上的Jexus服务器
  6. Mysql存储引擎比较
  7. [算法]——快速排序(Quick Sort)
  8. springmvc+bootstrap+jquerymobile完整搭建案例(提供下载地址)
  9. .net core和angular2之前端篇—1
  10. KOTLIN开发语言文档(官方文档) -- 2.基本概念