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的匿名内部类

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

参考资料:

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 运行在那个线程的更多相关文章

  1. handler.postDelayed(new Runnable()){ }运行在主线程吗

    答案:是的. handler.postDelayed(new Runnable() { @Override public void run() { tv_word.setVisibility(View ...

  2. Android查缺补漏(线程篇)-- AsyncTask的使用及原理详细分析

    本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8515304.html 一.AsyncTask的使用 AsyncTask是一种轻 ...

  3. 为什么说android UI操作不是线程安全的

    转载于:http://blog.csdn.net/lvxiangan/article/details/17218409#t2 UI线程及Android的单线程模型原则 使用Worker线程 Commu ...

  4. Android平台调用Web Service:线程返回值

    接上文 前文中的遗留问题 对于Java多线程的理解,我曾经只局限于实现Runnable接口或者继承Thread类.然后重写run()方法.最后start()调用就算完事,可是一旦涉及死锁以及对共享资源 ...

  5. MTK Android Camera运行流程

    Android Camera 运行流程 总体架构1.CameraService服务的注册2.Client端的应用层到JNI层Camera App-JNI3.Client到Service的连接4.HAL ...

  6. Android Studio学习随笔-UI线程阻塞以及优化

    我们在使用手机的时候,经常会遇到一个问题:先是卡死,然后跳出该程序无响应,是否关闭的提示(当然有可能是我们手机性能太差=.=)这是因为线程的阻塞引起的,在这里我讲述一下UI线程,一般处理程序会在UI线 ...

  7. Android应用运行过程(转)

    源:Android应用运行过程 首先,ActivityThread从main()函数开始执行,调用prepareMainLooper()为UI线程创建一个消息队列(MessageQueue). 然后创 ...

  8. Android中让多个线程顺序执行探究

    线程调度是指按照特定机制为多个线程分配CPU的使用权. 有两种调度模型:分时调度模型和抢占式调度模型. 分时调度模型:是指让所有的线程轮流获得cpu的使用权,并且平均分配每个线程占用的CPU的时间片. ...

  9. 【转】实践最有效的提高Android Studio运行、编译速度方案

    原文:https://blog.csdn.net/xwh_1230/article/details/60961723 实践最有效的提高Android Studio运行.编译速度方案 最有效提升Andr ...

随机推荐

  1. 【Flutter学习】之深入浅出 Key

    一,前言 在开发 Flutter 的过程中你可能会发现,一些小部件的构造函数中都有一个可选的参数——Key.在这篇文章中我们会深入浅出的介绍什么是 Key,以及应该使用 key 的具体场景. 二,什么 ...

  2. linux c(一)Helloworld

    终端的屏幕上输入命令如下: 使用vi helloworld.c打开helloworld.c文件,写下如下代码:

  3. 队列Queue--数组实现

    队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插入操作的端称为队尾,进行删除操作的 ...

  4. intellij免费激活码

    IDEA官方下载地址:https://www.jetbrains.com/idea/nextversion/ IntelliJ IDEA 2019.2最新版本免费激活码 支持IDEA所有版本 正版授权 ...

  5. vbox出现Failed to opencreate the internal network错误,无法启动虚拟机

    vbox出现Failed to opencreate the internal network错误,无法启动虚拟机 标签(空格分隔): 未分类 问题 Failed to open/create the ...

  6. 一个线上Java空指针问题的排查经过

    某天,运营反馈,某商品下单异常 1.原来是一个空指针报错 根据用户输入的下单关键信息搜索日志系统看到如下报错 stackTrace: "java.lang.NullPointerExcept ...

  7. Jackson读取列表

    List<MyBean> result = mapper.readValue(src, TypeFactory.collectionType(ArrayList.class, MyBean ...

  8. 关于原生js中ie的attacheEvent事件用匿名函数改变this指向后,不能用detachEvent删除绑定事件的解决办法?

    博客搬迁,给你带来的不便,敬请谅解! http://www.suanliutudousi.com/2017/11/28/%e5%85%b3%e4%ba%8e%e5%8e%9f%e7%94%9fjs%e ...

  9. CF585F Digits of Number Pi

    题目 把\(s\)串所有长度为\(\lfloor \frac{d}{2}\rfloor\)的子串插入一个ACAM中,之后数位dp就好了,状态是\(dp_{i,j,0/1}\)第\(i\)位,在ACAM ...

  10. MVC5+EF6 完整教程

    随笔分类 - MVC ASP.NET MVC MVC5+EF6 完整教程17--升级到EFCore2.0 摘要: EF Core 2.0上周已经发布了,我们也升级到core 文章内容基于vs2017, ...