Runnable并不一定新开线程

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

前面谈到过Threads与Runnable的区别,这里再补充一个特殊的区别。

extends Thread一定新开一个线程,但Runnable不一定新开线程(所谓新开线程,指非UI线程):

① 如果是implements Runnable,像extends Thread一样,是新开了线程。

②如果是匿名Runnable对象new Runnable() {...},是把Runnable对象以Message形式post到UI线程的Looper里执行。


1) 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. ”

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

 mHandler.post(new Runnable(){......}) 好像是new 了一个 interface, 其实是new的一个实现Runnable的匿名内部类(Inner Anonymous Class),这是很简练的写法!

上面的代码可以看成是: new anonymousClass() implement Runnable{......}

Runnable是一个接口,不是一个线程,一般要开线程的类会implements Runnable。

所以:

如果我们使用匿名内部类,则是运行在UI主线程的;

如果我们使用implements这个Runnable接口的线程类,则是运行在另一个新线程的。


2) View也可以post一个Runnable对象到UI线程你去执行:

View.post(Runnable)

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.

具体来说,View.post(Runnable)这个函数的工作原理如下:

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

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

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

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



Runnable 并不一定开一个线 Runnable 并不一定开一个线,比如下面的调用方法就是运行在UI主线中的:      Handler mHandler=new Handler();      mHandler.post(new Runnable(){         @Override public void run()         { // TODO Auto-generated method st 阅读详情

相关推荐

浅谈new Runnable()

转自:https://blog.csdn.net/c_p_h/article/details/70473673?locationNum=1&fps=1 参考: https://www.cnblogs.com/lanzhi/p/6467266.html //匿名内部类中关于new Runnable()的使用 http://wiki.jikexueyuan.com/project/jav...

平凡之路 3万+

匿名内部类中关于new Runnable()的使用

匿名内部类也就是没有名字的内部类,正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写。 但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口 1、继承一个父类的匿名内部类实现: abstract class People { public abstract void eat(); } public class De...

大大飞的博客 2997

new Thread(new Runnable(){})

JAVA是面向对象的,也就是说,对于一个方法等,它需要什么类型的对象,只要传入就可以了。 像这里,Thread类的构造方法中,需要一个实现了Runnable接口的对象,而new就是生成了个Runnable接口下的一个实例对象。 同等与这种写法,实例化了一个Runnable接口子类的实例 Thread t=new Thread(new MyRunnable()); public class MyRunnable implements Runnable{ @Override public void run(

麦七的博客 3万+

Java 高级应用-多线-(一)实现 Runnable 接口与继承 Thread 类

Java 高级应用-多线-实现 Runnable 接口与继承 Thread 类

weixin_45817985的博客 3445

Runnable( )并不一定开线

转自:https://blog.csdn.net/ricefcc/article/details/41912113 参考: http://www.cnblogs.com/xirihanlin/archive/2011/04/11/2012746.html //Android中的Handler,Looper,MessageQueue和thread https://blog.csdn.net/l...

平凡之路 1921

Runnable不是要开线

 这是由一个故事引起的. 故事主人公发了一个帖子: 求解决android.os.NetworkOnMainThreadException http://www.eoeandroid.com/thread-325472-1-1.html 这位楼主找到这个问题,然后明白在版本里不应该在主线里面做网络操作. 于是楼主找到了这篇ice的blog: 解决android.os.N

最帅的明天专栏 1768

android 开线 定时器,线的使用 三种方式 Android中常用定时器

Java代码 packagecom.quding.thread;importandroid.app.Activity;importandroid.os.Bundle;importandroid.os.Handler;importandroid.os.Looper;importandroid.os.Message;importandroid.util.Log;importandroid.widge...

weixin_28785069的博客 425

Java还可以通过内部类开线

1. 所谓内部类,就是类中之类, 也就是无论我们是通过继承Thread类来开线,还是通过实现Runnable接口来开 线,这个线类即可以写在 主类之外,也可以写在主类之内。不多说, 直接看代码就明白了。 public class ChatServerData { public void start(){ try{ ss1 = new ServerSocket(6666); ...

qq_36499794的博客 355

Java中匿名类开线

1.   顾名思义,本篇博客主要 介绍的是使用 匿名类如何开线,或许大部分人都没听说过匿名类开线,但是没关系,直接 上代码,一看你就懂。 package testThread; public class test1 { public static void main(String[] args) { new Thread() { //这样的方式开线不需要去继承Thread...

qq_36499794的博客 1162

Android Runnable 运行在那个线

Android Runnable 运行在那个线

jfdtygv的博客 120

线里面开线_Java 线同步(Synchronized)

点击上方蓝色字体,关注我们进和线有什么区别Synchronized 的本质是什么死锁是什么乐观锁和悲观锁是什么volatile 关键字有什么作用本篇记录Java多线和线同步(synchronized),带着问题学习才是最有效的方法。下面会对上述问题由浅入深,进行原理性的讲解,大部分会用最简单的例子讲解到原理。理解了才是自己的知识。开启线先来个最简单的如何开启一个新线程:Thre...

weixin_39976081的博客 705

Java中的两种开线方式

1.  使用 extends继承Thread类,然后在 主函数中 调用创建的这个类,创建其类对象,然后再利用对象访问start 方法。 package testThread; public class thr { public static void main(String args[]) throws InterruptedException{ for(int j =0;j<2...

qq_36499794的博客 163

java简易开线处理

直接建一个异步线new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000); //处理需要实现的 } catch (Exception e) { e.printStackTrace(); } } ...

daxiong_的博客 504

android view.post作用,Android View.post(Runnable )

Runnable 并不一定开一个线,比如下面的调用方法就是运行在UI主线中的:Handler mHandler=new Handler();mHandler.post(new Runnable(){@Overridepublic void run(){// TODO Auto-generated method stub}});官方对这个方法的解释如下,注意其中的:“The runnable...

weixin_30814737的博客 303

Android View.post(Runnable )

Runnable 并不一定开一个线,比如下面的调用方法就是运行在UI主线中的: Handler mHandler=new Handler();        mHandler.post(new Runnable(){          @Override public void run()          {  // TODO Auto-generated me

cys1991的专栏 971

开线的一般写法

1.开子线做耗时: private HandlerThread mHandlerThread; private Handler mHandler; private Runnable mClearCacheRunnable = new Runnable() { @Override public void run() { xxx耗时操作; } }; mHandlerThread = new HandlerThread(“xxxName”); mHandlerThre.

emmmsuperdan的博客 281

关于Handler.post(Runnable runnable)的解释

http://stackoverflow.com/questions/5316393/handler-looper-implementation-in-android http://developer.android.com/reference/android/os/Handler.html#post(java.lang.Runnable) Causes the Runnable r to b...

java开发指南博客 【转载】 532

开线 得屏幕高宽 画图

public class MainActivity extends AppCompatActivity { View v=null; int Width,Height; int x,y; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(

radishkill的博客 305
上一篇: 线程的两种玩法:extends Thread和implements Runnable
下一篇: Java内部类使用总结
知行合一365
博客等级 码龄17年 13粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值