我们说handler是开启了另外一个线程,而且看代码的话确实是这样,实现了runnable接口,这在java中就是开启了一个线程,但是情况中的是这样吗?我们不妨来做个试验,如下

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler; public class handlerThread extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); Handler handler = new Handler();
handler.post(r);
System.out.println("activity线程ID:"+Thread.currentThread().getId());
System.out.println("activity线程name:"+Thread.currentThread().getName());
} Runnable r = new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
System.out.println("handler线程ID:"+Thread.currentThread().getId());
System.out.println("handler线程name:"+Thread.currentThread().getName());
try {
Thread.sleep();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} };
}

运行结果

其实,当我看到这里的时候也不敢相信,但是事实就是这样,handler没有重新开启一个线程,而是跟activity在同一个线程里,但是这种写法也就非常接近java的标准线程的写法了,难怪会误导人,如下是java的标准线程写法。

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler; public class handlerThread extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // Handler handler = new Handler();
// handler.post(r);
Thread t = new Thread(r);
t.start();
System.out.println("activity线程ID:"+Thread.currentThread().getId());
System.out.println("activity线程name:"+Thread.currentThread().getName());
} Runnable r = new Runnable(){ @Override
public void run() {
// TODO Auto-generated method stub
System.out.println("handler线程ID:"+Thread.currentThread().getId());
System.out.println("handler线程name:"+Thread.currentThread().getName());
try {
Thread.sleep();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} };
}

运行结果如下:

这里就才是我们这种想要的结果,两者比较我们就会发现,handler虽然实现了 runnable接口,但是却并没有启动一个线程,而是直接调用run方法。那andriod为什么要这样设计呢,既然不启动新的线程,为什么还要多此一 举来实现runnable接口呢,我们继续探讨,下次再说。

Android handler真的是重新启动一个线程吗?的更多相关文章

  1. [原创]Android Handler使用Message的一个注意事项

    最近发现了一个莫名其妙的问题,在使用Handler.post(Runnable)这个接口时,Runnable有时候没有运行,非常奇怪,后来发现是因为调用Handler.removeMessage()时 ...

  2. android Handler介绍

    Handler使用介绍: Handler根据接收的消息,处理UI更新.Thread线程发出消息,通知Handler更新UI. Handler mHandler = new Handler() {  p ...

  3. Android Handler学习笔记

    已经习惯了挖坑不填,继续任性一下,周一到周五继续挖坑,每周六周日负责填坑. 1.从Android UI线程谈起 出于性能考虑,Android 中的UI操作并不是线程安全的,所以Android中规定只能 ...

  4. Java 如何正确停止一个线程

    自己在做实验性小项目的时候,发现自己遇到一个问题:如何控制线程的"死亡"? 首先,如何开启一个线程呢? 最简单的代码: public class Main { public sta ...

  5. 死磕 java线程系列之自己动手写一个线程池

    欢迎关注我的公众号"彤哥读源码",查看更多源码系列文章, 与彤哥一起畅游源码的海洋. (手机横屏看源码更方便) 问题 (1)自己动手写一个线程池需要考虑哪些因素? (2)自己动手写 ...

  6. Java里一个线程两次调用start()方法会出现什么情况

    Java的线程是不允许启动两次的,第二次调用必然会抛出IllegalThreadStateException,这是一种运行时异常,多次调用start被认为是编程错误. 如果业务需要线程run中的代码再 ...

  7. Android Handler机制 (一个Thead中可以建立多个Hander,通过msg.target保证MessageQueue中的每个msg交由发送message的handler进行处理 ,但是 每个线程中最多只有一个Looper,肯定也就一个MessageQuque)

    转载自http://blog.csdn.net/stonecao/article/details/6417364 在android中提供了一种异步回调机制Handler,使用它,我们可以在完成一个很长 ...

  8. android为什么不允许新开启一个线程来更新UI,而是用handler来更新界面

    下面是快速创建一个新线程的方法: 第一种:直接创建子线程并启动      new Thread() {@Overridepublic void run() {     //这里写入子线程需要做的工作  ...

  9. 源码分析Android Handler是如何实现线程间通信的

    源码分析Android Handler是如何实现线程间通信的 Handler作为Android消息通信的基础,它的使用是每一个开发者都必须掌握的.开发者从一开始就被告知必须在主线程中进行UI操作.但H ...

随机推荐

  1. Linux驱动开发之开篇--HelloWorld

    Linux驱动的编写,大致分为两个过程,第一个过程为测试阶段,即为某一具体的设备,添加必要的驱动模块,为了节省编译时间,需要将代码单独放在一处,在编译时,只需要要调用内核的头文件即可:第二个过程为布置 ...

  2. WPF-控件-ControlTemplate生成的控件

    <Window x:Class="由ControlTemplate生成的控件.MainWindow" xmlns="http://schemas.microsoft ...

  3. Rac & DG

    Rac环境: RAC版本异同:[10R2,11R1(和10类似)],11R2,12c: 目录: 10.2的ASM需要单独的目录(oracle home):rdbms home,asm home, cr ...

  4. APACHE 403 FORBIDDEN错误的解决办法之一

    打开 apache的配置文件httpd.conf,找到这段代码: Options FollowSymLinksAllowOverride NoneOrder deny,allowDeny from a ...

  5. Jquery post 传递数组给asp.net mvc方法

    以批量删除数据为例  做批量删除会需要传递要删除的数据ID数组 function RemoveLog(){ var postModel=[]; //遍历复选框获取要删除的数据ID 存放到数组中  $( ...

  6. c++类中的静态成员

    静态成员和非静态成员的区别: 类静态成员用static修饰,类的静态成员属于类本身,而不属于类的某个具体对象,静态成员被类的所有对象共享,因此某个对象对静态成员(数据成员)的修改对其对象是可见的.而类 ...

  7. 野指针及c++指针使用注意点

    避免野指针的产生 “野指针”的成因主要有: 1)指针变量没有被初始化.任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气.所以,指针变量在创建的同时应当被初始化,要么将指 ...

  8. Zend Studio 12.0.2正式版发布和破解方法,zend studio 12.0.1汉化,相式设置为Dreamweaver,空格缩进为4个, 代码默认不折叠的设置,Outline中使用的图形标志,代码颜色之eot设置。

    背景:zend studio 12.0.2 修复了一个12.0.1的:  Fixed problem with referenced variables marked as undefined,我都说 ...

  9. Xcode8之后 XMPP 重定义问题 Redefinition of module 'dnssd'

    在升级Xcode到8之后,原来的关于XMPP的项目运行报错,错误信息为: Redefinition of module 'dnssd' 系统和XMPP框架同时用到了 'dnssd',大概就是错误的原因 ...

  10. FMS (端口问题)如何穿透防火墙

    转自http://www.cnblogs.com/zhchongyao/archive/2010/01/22/1653803.html 先是管理端口,就是fms2_console文件连接到server ...