Handler 原理分析和使用(二)
在上篇 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 原理分析和使用(二)的更多相关文章
- Handler 原理分析和使用(一)
我为什么写Handler,原因主要还在于它在整个 Android 应用层面非常之关键,他是线程间相互通信的主要手段.最为常用的是其他线程通过Handler向主线程发送消息,更新主线程UI. 下面是一个 ...
- Handler 原理分析和使用之HandlerThread
前面已经提到过Handler的原理以及Handler的三种用法.这里做一个非常简单的一个总结: Handler 是跨线程的Message处理.负责把Message推送到MessageQueue和处理. ...
- Handler系列之原理分析
上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...
- [转]Handler MessageQueue Looper消息循环原理分析
Handler MessageQueue Looper消息循环原理分析 Handler概述 Handler在Android开发中非常重要,最常见的使用场景就是在子线程需要更新UI,用Handler ...
- Mybatis插件原理分析(二)
在上一篇中Mybatis插件原理分析(一)中我们主要介绍了一下Mybatis插件相关的几个类的源码,并对源码进行了一些解释,接下来我们通过一个简单的插件实现来对Mybatis插件的运行流程进行分析. ...
- Mybatis接口编程原理分析(二)
在上一篇博客中 Mybatis接口编程原理分析(一)中我们介绍了MapperProxyFactory和MapperProxy,接下来我们要介绍的是MapperMethod MapperMethod:它 ...
- Faster RCNN原理分析(二):Region Proposal Networks详解
Faster RCNN原理分析(二):Region Proposal Networks详解 http://lib.csdn.net/article/deeplearning/61641 0814: A ...
- java基础进阶二:HashMap实现原理分析
HashMap实现原理分析 1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端. 数组 数组存储区间是连续的,占用内存严重,故空间复杂的很大.但数组的二 ...
- Android 4.4 KitKat NotificationManagerService使用具体解释与原理分析(二)__原理分析
前置文章: <Android 4.4 KitKat NotificationManagerService使用具体解释与原理分析(一)__使用具体解释> 转载请务必注明出处:http://b ...
随机推荐
- MOSS母板页制作 学习笔记(一)
转:http://xiachanghao1990.blog.163.com/blog/static/4869602420114235536573/ 母版页制作其实应该算是一个比较基础的工作,但是熟练制 ...
- android报错——findViewById报错
通過ID找到Layout的 VIEW控件.,比如你的控件Button ID為"@+id/button01" 就可以通過這樣Button btn=(Button)findView ...
- python urllib2模块携带cookie
今天干活遇到一个事.有一些网站的一些操作非得要求你登陆才能做,比如新浪微博,你要随便看看吧,不行,非得让你登陆了才能看,再比如一些用户操作,像更改自己的资料啦,个人的隐私啦巴拉巴拉的.想抓取这样的ur ...
- slua 中使用 lua5.3
因为我们服务器极有可能要迁移到 skynet 上,它基于 lua5.3,而服务器和客户端会公用很多lua代码,所以在考虑在客户端 slua 中使用 lua5.3. 经过编译后,发现 slua 对 lu ...
- 研磨设计模式解析及python代码实现——(三)适配器模式(Adapter)
一.适配器模式定义 将一个类的接口转换成另外一个接口,适配器模式使得原本由于接口不兼容,而不能在一起工作的哪些类能够在一起工作. 二.python 实现 import string import cP ...
- C语言中可变参数的用法
原文地址: http://blog.csdn.net/wooin/archive/2006/04/29/697106.aspx 我们在C语言编程中会遇到一些参数个数可变的函数,例如printf() ...
- Shell break和continue命令
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,像大多数编程语言一样,Shell也使用 break 和 continue 来跳出循环. break命令 break命令允许跳出所有循环(终止 ...
- java-mina(nio 框架)
mina是对nio的具体实现.是目前比较高效和流行的nio框架了. 下面是对使用mina进行通讯的一个简单demo,后面再用mina写一个RPC的简单框架. mina主要包括: (使用的mina版 ...
- ReactiveCocoa框架学习1
写block直接使用inline block的声明类型 在ARC中使用strong,如果不使用strong,则会被销毁 在非ARC中使用copy block在开发中的使用场景 把block保存到对象中 ...
- spring使用ehcache
spring本身内置了对Cache的支持,之前记录的是基于Java API的ConcurrentMap的CacheManager配置,现使用ehcache实现. 1.声明对cache的支持 <b ...