在上篇 Handler 原理分析和使用(一)中,介绍了一个使用Handler的一个简单而又常见的例子,这里还有一个例子,当然和上一篇的例子截然不同,也是比较常见的,实例如下。

 import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private TextView myTextView;
private Button myButton;
private Handler myHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myHandler = new Handler();
myTextView = (TextView)this.findViewById(R.id.text_view);
myButton = (Button)this.findViewById(R.id.post);
myButton.setOnClickListener(this);
} @Override
public void onClick(View view) {
int id = view.getId();
if(id == R.id.post){
Runnable updateUI = new Runnable() {
@Override
public void run() {
myTextView.setText("I get Post Message");
}
};
//将该线程发送到主线程运行
myHandler.post(updateUI);
}
}
}

实际运行这个例子,点击Button之后,TextView文字内容会变成“I get Post Message”。为什么会是这样,我们从源码开始着手查看。

先看Handler的post(Runnable)方法(post还有几个姊妹方法,这里不再一一论述,都是殊途同归)。源码如下:

 public final boolean post(Runnable r)
{
return sendMessageDelayed(getPostMessage(r), 0);
}

调用了sendMessageDelayed(...), 先看getPostMessage(r),源码如下:

 private static Message getPostMessage(Runnable r) {
//获取消息池中的一个消息
Message m = Message.obtain();
//将Runnable作为消息的callback
m.callback = r;
return m;
}

在看sendMessageDelayed(Message,int)的源码:(在Handler 原理分析和使用(一)中有说明)

 public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
if (delayMillis < 0) {
delayMillis = 0;
}
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
//绑定Handler
msg.target = this;
if (mAsynchronous) {
msg.setAsynchronous(true);
}
//将Message推入MessageQueue
return queue.enqueueMessage(msg, uptimeMillis);
}

实际上和sendMessage(Message)一样的流程。当然了紧接着Looper.loop()。然后调用到dispatchMessage(Message) 该方法需要在此重新说明。看源码:

 public void dispatchMessage(Message msg) {
if (msg.callback != null) {
//如果message的callback不为空,则
handleCallback(msg);
} else { if (mCallback != null) {
//如果Handler的callback不为空,则
if (mCallback.handleMessage(msg)) {
return;
}
}
//处理Message
handleMessage(msg);
}
}

在进入handleCallback(Message)方法查看源码:

 private static void handleCallback(Message message) {
//直接执行run方法
message.callback.run();
}

注意,此时message已经是主线程对象。因此调用run方法就是在主线程中运行。

此外还需要注意,runnable要处理的内容会在主线程中处理,因此不能够占用太多的时间,从而造成ANR。

--------------------------------------------------------------------------------------------

之所以用一条线隔开,是因为还有一个实例需要说明。请注意dispatchMessage(message)里面的这段代码:

 if (mCallback != null) {
//如果Handler的callback不为空,则
if (mCallback.handleMessage(msg)) {
return;
}
}

这个mCallback是从哪里来,这个有引出Handler的另一个使用方法。

首先来看Handler的初始化方法,有一下几个:

1. publicHandler()

2. publicHandler(Callback)

3. publicHandler(Looper)

4. publicHandler(Looper, Callback)

第1,3个一眼看去就明白。第4个只要明白第2个也就通了。

关键点,Callback是什么?是一个接口。源码如下:

 public interface Callback {
public boolean handleMessage(Message msg);
}

该接口实际上是要求实现handleMessage(Message)方法,相信这个方法大家都不陌生。

再看该初始化方法:

 Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
return false;
}
});

这里已经很明显了。就是重新定义了handleMessage方法。那么在dispatchMessage方法中如果发现mCallback不为空,则所有的消息都执行该Callback定义的handleMessage(Message).

具体的例子不想写了。今天就到这里吧。太累了。明天不在深入,而是扩展。

Handler 原理分析和使用(二)的更多相关文章

  1. Handler 原理分析和使用(一)

    我为什么写Handler,原因主要还在于它在整个 Android 应用层面非常之关键,他是线程间相互通信的主要手段.最为常用的是其他线程通过Handler向主线程发送消息,更新主线程UI. 下面是一个 ...

  2. Handler 原理分析和使用之HandlerThread

    前面已经提到过Handler的原理以及Handler的三种用法.这里做一个非常简单的一个总结: Handler 是跨线程的Message处理.负责把Message推送到MessageQueue和处理. ...

  3. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  4. [转]Handler MessageQueue Looper消息循环原理分析

    Handler MessageQueue Looper消息循环原理分析   Handler概述 Handler在Android开发中非常重要,最常见的使用场景就是在子线程需要更新UI,用Handler ...

  5. Mybatis插件原理分析(二)

    在上一篇中Mybatis插件原理分析(一)中我们主要介绍了一下Mybatis插件相关的几个类的源码,并对源码进行了一些解释,接下来我们通过一个简单的插件实现来对Mybatis插件的运行流程进行分析. ...

  6. Mybatis接口编程原理分析(二)

    在上一篇博客中 Mybatis接口编程原理分析(一)中我们介绍了MapperProxyFactory和MapperProxy,接下来我们要介绍的是MapperMethod MapperMethod:它 ...

  7. Faster RCNN原理分析(二):Region Proposal Networks详解

    Faster RCNN原理分析(二):Region Proposal Networks详解 http://lib.csdn.net/article/deeplearning/61641 0814: A ...

  8. java基础进阶二:HashMap实现原理分析

    HashMap实现原理分析 1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二 ...

  9. Android 4.4 KitKat NotificationManagerService使用具体解释与原理分析(二)__原理分析

    前置文章: <Android 4.4 KitKat NotificationManagerService使用具体解释与原理分析(一)__使用具体解释> 转载请务必注明出处:http://b ...

随机推荐

  1. MOSS母板页制作 学习笔记(一)

    转:http://xiachanghao1990.blog.163.com/blog/static/4869602420114235536573/ 母版页制作其实应该算是一个比较基础的工作,但是熟练制 ...

  2. android报错——findViewById报错

    通過ID找到Layout的 VIEW控件.,比如你的控件Button ID為"@+id/button01"   就可以通過這樣Button btn=(Button)findView ...

  3. python urllib2模块携带cookie

    今天干活遇到一个事.有一些网站的一些操作非得要求你登陆才能做,比如新浪微博,你要随便看看吧,不行,非得让你登陆了才能看,再比如一些用户操作,像更改自己的资料啦,个人的隐私啦巴拉巴拉的.想抓取这样的ur ...

  4. slua 中使用 lua5.3

    因为我们服务器极有可能要迁移到 skynet 上,它基于 lua5.3,而服务器和客户端会公用很多lua代码,所以在考虑在客户端 slua 中使用 lua5.3. 经过编译后,发现 slua 对 lu ...

  5. 研磨设计模式解析及python代码实现——(三)适配器模式(Adapter)

    一.适配器模式定义 将一个类的接口转换成另外一个接口,适配器模式使得原本由于接口不兼容,而不能在一起工作的哪些类能够在一起工作. 二.python 实现 import string import cP ...

  6. C语言中可变参数的用法

    原文地址: http://blog.csdn.net/wooin/archive/2006/04/29/697106.aspx   我们在C语言编程中会遇到一些参数个数可变的函数,例如printf() ...

  7. Shell break和continue命令

    在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,像大多数编程语言一样,Shell也使用 break 和 continue 来跳出循环. break命令 break命令允许跳出所有循环(终止 ...

  8. java-mina(nio 框架)

    mina是对nio的具体实现.是目前比较高效和流行的nio框架了. 下面是对使用mina进行通讯的一个简单demo,后面再用mina写一个RPC的简单框架.   mina主要包括: (使用的mina版 ...

  9. ReactiveCocoa框架学习1

    写block直接使用inline block的声明类型 在ARC中使用strong,如果不使用strong,则会被销毁 在非ARC中使用copy block在开发中的使用场景 把block保存到对象中 ...

  10. spring使用ehcache

    spring本身内置了对Cache的支持,之前记录的是基于Java API的ConcurrentMap的CacheManager配置,现使用ehcache实现. 1.声明对cache的支持 <b ...