Handler之创建子线程Handler

Android的消息机制实现步骤:
①创建当前线程的looper
②创建当前线程的handler
③调用当前线程looper的loop方法

要实现创建子线程Handler,按常理应该如此

public class ChildThreadHandlerActivity extends Activity {private MyThread childThread;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_handler);childThread = new MyThread();childThread.start();Handler childHandler = new Handler(childThread.childLooper){//这样之后,childHandler和childLooper就关联起来了。public void handleMessage(Message msg) {};};}private class MyThread extends Thread{public Looper childLooper;@Overridepublic void run() {Looper.prepare();//创建与当前线程相关的LooperchildLooper = Looper.myLooper();//获取当前线程的Looper对象Looper.loop();//调用此方法,消息才会循环处理}}
}

这样就完成了子线程Handler的创建,But 我们运行代码会发现此代码一会崩溃一会不崩溃,发现Looper指针为空,我不是在子线程的run方法中初始化Looper对象了么,当你statr子线程的时候,虽然子线程的run方法得到执行,但是主线程中代码依然会向下执行,造成空指针的原因是当我们new Handler(childThread.childLooper)的时候,run方法中的Looper对象还没初始化。当然这种情况是随机的,所以造成偶现的崩溃。

HandlerThread类就是解决这个问题的关键所在

public class HandlerThreadActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_handler);TextView textView = (TextView) findViewById(R.id.tv);textView.setText("HandlerThreadActivity.class");HandlerThread handlerThread = new HandlerThread("HandlerThread");handlerThread.start();Handler mHandler = new Handler(handlerThread.getLooper()){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);Log.d("HandlerThreadActivity.class","uiThread2------"+Thread.currentThread());//子线程}};Log.d("HandlerThreadActivity.class","uiThread1------"+Thread.currentThread());//主线程mHandler.sendEmptyMessage(1);}
}

创建HandlerThread对象的时候,有个参数,是指定线程名字的。上面的代码不管运行多少次都不会奔溃!!!并且这种方法创建的handler的handleMessage方法运行在子线程中。所以我们可以在这里处理一些耗时的逻辑。到此我们完成了主线程给子线程发通知,在子线程做耗时逻辑的操作。下面我们去看看源码,看看为什么使用HandlerThread就可以避免空指针那?

public Looper getLooper() {if (!isAlive()) {return null;}// If the thread has been started, wait until the looper has been created.synchronized (this) {while (isAlive() && mLooper == null) {try {wait();} catch (InterruptedException e) {}}}return mLooper;}

HandlerThread类的getLooper方法如上,我们看到当我们获取当前线程Looper对象的时候,会先判断当前线程是否存活,然后还要判断Looper对象是否为空,都满足之后才会返回给我Looper对象,否则处于等待状态!!既然有等待,那就有唤醒的时候,在那里那???我们发现HandlerThread的run方法中,有如下代码:

@Overridepublic void run() {mTid = Process.myTid();Looper.prepare();synchronized (this) {mLooper = Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid = -1;}

说明了什么那???HandlerThread类start的时候,Looper对象就初始化了,并唤醒之前等待的。所以HandlerThread很好的避免了之前空指针的产生。所以以后要想创建非主线程的Handler时,我们用HandlerThread类提供的Looper对象即可

Handler之创建子线程Handler相关推荐

  1. Android创建子线程和回调主线程的几种方式

    一. 创建子线程//通过继承threadpublic class JNThread1 extends Thread {public JNThread1(String name){super(name) ...

  2. python多线程的使用(导入线程模块、创建子线程任务、启动子线程任务、获取当前执行的线程号)

    1. 导入线程模块 #导入线程模块 import threading 2. 线程类Thread参数说明 Thread([group [, target [, name [, args [, kwarg ...

  3. python创建多线程_Python 多线程,threading模块,创建子线程的两种方式示例

    本文实例讲述了Python 多线程,threading模块,创建子线程的两种方式.分享给大家供大家参考,具体如下: GIL(全局解释器锁)是C语言版本的Python解释器中专有的,GIL的存在让多线程 ...

  4. 运行错误: QObject: 无法创建子线程, 因为父线程位于不同的线程? 到底是什么鬼?

    运行错误: QObject: 无法创建子线程, 因为父线程位于不同的线程?  到底是什么鬼? (Parent is QThread(0x7ffe4a5a1280), parent's thread i ...

  5. Python 创建子线程

    主线程主要是进行一些界面操作.子线程就进行一些耗时的获取数据.处理数据等操作,然后返回数据给主线程,让主线程更新 UI,这样才不会让程序出现无响应的现象. 如果把获取数据的操作放在主线程,那么主线程就 ...

  6. Android中创建子线程的三种方式

    1.新建一个类继承自Thread,并重写run()方法,并在里面编写耗时逻辑. class ThreadTest extends Thread {@Overridepublic void run() ...

  7. java怎么创建子线程_Java创建子线程的两种方法

    摘要: 其实两种方法归结起来看还是一种,都是利用Thread的构造器进行创建,区别就是一种是无参的,一种是有参的. 一.继承Thread线程类: 通过继承Thread类,重写run方法,子类对象就可以 ...

  8. 子线程创建Handler

    首先,我们平时直接创建的Handler实例默认是在主线程,是可以直接更新UI操作,而在子线程创建的Handler则不可以直接更新UI操作(可以通过runUIThread(Runnable run)切换 ...

  9. Handler消息机制(四):子线程可以创建Handler吗

    默认情况下,ActivityThread类为我们创建的了主线程的Looper和消息队列,所以当你创建Handler之后发送消息的时候,消息的轮训和handle都是在ui线程进行的.这种情况属于子线程给 ...

最新文章

  1. 做出的C++选择以及背后的原因
  2. 聊一聊:你碰到过哪些操蛋的文档?
  3. 消息中间件之ActiveMQ 入门
  4. oracle 连续5分钟_3-1!10分钟3球杀入前四,连续5个客场大逆转,名字叫曼联
  5. Linux服务器IP下了,linux – DDOS攻击下的服务器 – 如何查找IP?
  6. Val编程-系统架构
  7. linux fstab解读
  8. 前端学习(1309):创建网站服务器
  9. 面向对象编程的五大基本原则
  10. python pipline_python中sklearn的pipeline模块实例详解
  11. java跑批任务_【spring配置】——spring整合Quartz定时器
  12. SQL 安装在DC上的问题
  13. Javascript六种数据类型及类型转换总结
  14. tomcat编码配置gbk_修改Tomcat编码方式的两种方法
  15. 在GitHub中上传本地项目
  16. 2022广东省安全员A证第三批(主要负责人)考试题库及答案
  17. 分布式游戏服务器设计
  18. Ozone Block Chunk文件的layout方式
  19. Python——列表与元组
  20. Microsoft Excel 2010表最多容纳的行数

热门文章

  1. implicit declaration of function 警告解决方法 (函数的隐式说明)
  2. 关于文献HEVC-The New Glod Standard For Video Compress的理解
  3. Linux 数据可视化工具
  4. 渗透测试-越权漏洞之垂直越权和水平越权
  5. 自主可控国产服务器思考
  6. Vultr新用户充值送50刀
  7. matlab学习笔记 bsxfun函数
  8. matlab两个for循环嵌套加速,使用bsxfun加速Matlab嵌套for循环
  9. Oracle增加修改删除字段
  10. Android混淆技术综述