Android异步通信——HandlerThread源码解析
来源:互联网 发布:图的广度优先遍历c语言 编辑:程序博客网 时间:2024/06/18 06:35
前面已经说过,每一个线程的ThreadLocal都保存了一个looper对象,这个looper对象只存在于安卓之中,通过这个looper,会不断地从消息队列中进行轮训,当有消息到达的时候,就会取出消息,进行处理。
构造函数
Handler正是结合了线程Thread以及Handler,大体上定义了一个线程,并且在启动线程时创建Looper,我们先来看看它的构造函数
//线程优先级默认为Process.THREAD_PRIORITY_DEFAULTpublic HandlerThread(String name)//自定义线程的名字和优先级public HandlerThread(String name, int priority)
优先级这个值必须是android.os.Process
,不能使用java.lang.Thread
的值,至于为什么,我们会在学习线程,并发编程的时候介绍到。
初始化线程以后,我们来看一下这个线程的run方法
@Override public void run() { //获取当前线程的线程id mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); //因为如果Looper还没创建好,有线程想要访问,那么该线程就会进行等待wait,直到这里当looper准备好以后,唤醒所有等待的线程 notifyAll(); } //设置线程优先级 Process.setThreadPriority(mPriority); //空方法,重写用于在执行loop之前的一些操作 onLooperPrepared(); Looper.loop(); //退出loop后,把线程id设为-1 mTid = -1; }
当我们在其他线程,获取这个线程对象的Looper的时候,调用getLooper对象
public Looper getLooper() { if (!isAlive()) { return null; } // 如果线程已经开启,如果Looper已经创建,往下执行, 否则等待 synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; }
HandlerThread的特殊之处就是loop会无限循环,当消息队列没有消息的时候,阻塞在那里,如果我们不主动关闭looper,跳出loop方法,那么这个线程将一直运行,直到系统把它杀死,当退出关闭线程之前,需要主动停止looper,让线程能够顺利跳出loop方法,然后线程执行完毕,关闭线程。调用下面两个方法跳出loop方法
主动退出Looper
public boolean quit() { Looper looper = getLooper(); if (looper != null) { looper.quit(); return true; } return false;}public boolean quitSafely() { Looper looper = getLooper(); if (looper != null) { looper.quitSafely(); return true; } return false; }
这两个方法大致上是一样的,分别调用的是Looper里面的两个处理消息队列的方法,在Looper里面实际上调用的是消息队列里面的quit方法
void quit(boolean safe) { if (!mQuitAllowed) { throw new IllegalStateException("Main thread not allowed to quit."); } synchronized (this) { if (mQuitting) { return; } mQuitting = true; if (safe) { //把消息队列里面还没执行的消息执行完,然后进行回收 removeAllFutureMessagesLocked(); } else { //直接回收所有的消息 removeAllMessagesLocked(); } // We can assume mPtr != 0 because mQuitting was previously false. nativeWake(mPtr); } }
虽然这是一个HandlerThread类,但是我们并没有源码中看到Handler的影子。熟知Handler的大佬们都知道,Handler其实只负责发送Message和处理Message,而轮训消息队列的Looper由始至终都和关联的Thread进行绑定,所以我们可以使用这个Thread提供的Looper自定义多个Handler,这些Handler发送的消息都会统一加入到Looper的消息队列中。
HandlerThread的常用用法
public class HandlerThreadActivity extends AppCompatActivity { private HandlerThread thread; private MyHandler handler; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); thread = new HandlerThread("sub"); thread.start(); // 使用HandlerThread对象来获取Looper handler = new MyHandler(thread.getLooper()); } class MyHandler extends Handler{ MyHandler(Looper looper){ super(looper); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); } } @Override protected void onDestroy() { super.onDestroy(); // 退出的时候应该关闭Looper thread.quitSafely(); }}
当handler发送消息的时候,就能够在异步处理该消息了。
- Android异步通信——HandlerThread源码解析
- Android异步通信——HandlerThread源码解析
- android HandlerThread源码解析
- 【Android】IntentService & HandlerThread源码解析
- 【Android】IntentService & HandlerThread源码解析
- Android——线程通信 HandlerThread
- 线程相关——HandlerThread、IntentService、ResultReceiver:结果接收者、AsyncTask:异步任务、Android中处理线程间通信的方式
- Android源码解析之(四)-->HandlerThread
- Android多线程-HandlerThread用法与源码解析
- Android多线程:HandlerThread使用&源码解析
- Android源码基础解析之HandlerThread
- Android 异步线程 HandlerThread
- HandlerThread源码解析
- HandlerThread 源码解析
- HandlerThread 源码解析
- HandlerThread使用&源码解析
- HandlerThread源码解析
- HandlerThread 源码解析
- 第六章 递归,内联,重载,作用域和存储类型
- 心理咨询预约如何在微信公众号如何快速实现
- freertos内核走读2——task任务调度机制(一)
- java锁之wait,notify(wait会释放锁,notify仅仅只是通知,不释放锁)(转)
- 每周阅读清单:Android 架构,小工具,Google 能访问了?
- Android异步通信——HandlerThread源码解析
- HDU 2159 FATE
- 上传本地项目到github
- 为什么非全站升级HTTPS不可?
- java语言基础(25)——面向对象(new对象的时候内存中发生了哪些变化)
- 20170323
- C++模拟DNS分布式查询
- JDBC(mysql)
- MyEclipse下java文件的图标是空心的J