Android Runnable 运行在那个线程

摘要:
上面的代码可以看作:newanonymousClass()implementingerface{[rewriteinterfacemethod]}Runnable是一个接口,而不是线程,一般线程将实现Runnable。因此,如果我们使用匿名内部类在UI主线程上运行,并且如果我们使用实现Runnable接口的线程类,则它们在相应的线程上运行。在post方法中,View获取当前线程的Handler,然后将操作对象发布到Handler。在处理程序中,它将传递的操作对象包装为Message,然后将其放入UI线程的消息循环中。当处理程序再次处理该消息时,会为其设置一个分支,该分支直接调用runnable的run方法。

Runnable 并不一定是新开一个线程,比如下面的调用方法就是运行在UI主线程中的:

Handler mHandler=new Handler();
mHandler.post(new Runnable(){
	@Override
	public void run() {
		// TODO Auto-generated method stub
	}
});

官方对这个方法的解释如下,注意其中的:“The runnable will be run on the user interface thread. ”

boolean android.view.View .post(Runnable action)

Causes the Runnable to be added to the message queue. The runnable will be run on the user interface thread.

Parameters: 
action The Runnable that will be executed. 
Returns: 
Returns true if the Runnable was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting.

 

我们可以通过调用handler的post方法,把Runnable对象(一般是Runnable的子类)传过去;handler会在looper中调用这个Runnable的Run方法执行。

Runnable是一个接口,不是一个线程,一般线程会实现Runnable。

有关 Looper、Handler,Thread 关系可以看这篇博客: 
Android 的消息队列模型 
http://www.cnblogs.com/ghj1976/archive/2011/05/06/2038469.html

 

这里我们看代码 mHandler.post(new Runnable(){  好像是new 了一个 interface, 其实是new的一个实现Runnable的匿名内部类(Inner Anonymous Class),这是很简练的写法。

上面的代码可以看成是: new anonymousClass() implement interface{ [改写interface method]}

 

Runnable是一个接口,不是一个线程,一般线程会实现Runnable。 所以如果我们使用匿名内部类是运行在UI主线程的,如果我们使用实现这个Runnable接口的线程类,则是运行在对应线程的。

具体来说,这个函数的工作原理如下:

View.post(Runnable)方法。在post(Runnable action)方法里,View获得当前线程(即UI线程)的Handler,然后将action对象post到Handler里。在Handler里,它将传递过来的action对象包装成一个Message(Message的callback为action),然后将其投入UI线程的消息循环中。在Handler再次处理该Message时,有一条分支(未解释的那条)就是为它所设,直接调用runnable的run方法。而此时,已经路由到UI线程里,因此,我们可以毫无顾虑的来更新UI。

如下图,前面看到的代码,我们这里Message的callback为一个Runnable的匿名内部类

这种情况下,由于不是在新的线程中使用,所以千万别做复杂的计算逻辑。

image

参考资料:

Android中的Handler, Looper, MessageQueue和Thread 
http://www.cnblogs.com/xirihanlin/archive/2011/04/11/2012746.html

Android系列之Message机制的灵活应用 
http://tech.ddvip.com/2010-07/1280393505158258_3.html

免责声明:文章转载自《Android Runnable 运行在那个线程》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇yaml文件的格式微网站自动显示 返回顶部 按钮 的代码下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Linux-c 线程锁

1 typedef struct_my_mutex { 2 pthread_mutex_t mutex; //互斥锁 3 pthread_mutexattr_t mta; //互斥锁属性 4 } my_mutex; 转自:http://blog.sina.com.cn/s/blog_8795b0970101il6g.html 在Posix Threa...

Javascript:再论Javascript的单线程机制 之 DOM渲染时机

Javascript:再论Javascript的单线程机制 之 DOM渲染时机 背景 Javascript是单线程事件驱动的,所有能看到的Javascript代码都是在一个线程执行,定时器回调和AJAX回调会在适当的时刻插入队列等待Javascript线程调度执行,今天想测试一下DOM渲染的线程与时机,具体的问题是: 修改DOM会立即显示在UI中吗? 一个...

Java多线程基础:进程和线程之由来

  在前面,已经介绍了Java的基础知识,现在我们来讨论一点稍微难一点的问题:Java并发编程。当然,Java并发编程涉及到很多方面的内容,不是一朝一夕就能够融会贯通使用的,需要在实践中不断积累。由于并发肯定涉及到多线程,因此在进入并发编程主题之前,我们先来了解一下进程和线程的由来,这对后面对并发编程的理解将会有很大的帮助。   下面是本文的目录大纲:  ...

QThread与QWidget使用

本文主要内容: 在任务一中,用 四 种方式实现:点击界面按钮,开线程运行一段程序,结果显示在一个Label上。1. 用不正确的方式得到看似正确的结果2. 用Qt Manual 和 例子中使用的方法3. 用一种好用但被Qt开发人员批判的方法4. 用一种被开发人员强烈推荐,但Qt Manual和例子中只字未提的方法 为了简单起见,本文只讲如何做及其结果是什么...

高德APP启动耗时剖析与优化实践(iOS篇)

前言最近高德地图APP完成了一次启动优化专项,超预期将双端启动的耗时都降低了65%以上,iOS在iPhone7上速度达到了400毫秒以内。就像产品们用后说的,快到不习惯。算一下每天为用户省下的时间,还是蛮有成就感的,本文做个小结。 (文中配图均为多才多艺的技术哥哥手绘)   启动阶段性能多维度分析 要优化,首先要做到的是对启动阶段的各个性能纬度做分析,...

Java之jdk命令行工具详解

        JPS---虚拟机进程状况工具常用的参数: -l 输出Java应用程序的main class的完整包 -q 仅显示pid,不显示其它任何相关信息 -m 输出传递给main方法的参数 -v 输出传递给JVM的参数。在诊断JVM相关问题的时候,这个参数可以查看JVM相关参数的设置 注:这个命令相信大多数java程序员都知晓、查找当前运行的jav...