Android多线程消息处理机制 HandlerThread案例分析
来源:互联网 发布:开车是什么意思网络语 编辑:程序博客网 时间:2024/06/06 03:11
前面在《Android多线程消息处理机制》讲过looper、thread的原理。
Main线程已经有了looper且已启动,意味着包含了消息队列。
所有没有指定looper对象而创建的handler,使用的都是main的looper。
这样的handler发送的message都放到了main线程的looper管理的消息队列中了。
发现有HandlerThread这个类,以前没用过,总以为是在Thread中内置了一个Handler。
在面试中也总是被问到,很心烦,于是索性来研究一下,正好前面也整体分析了looper,handler等技术。
Main线程已经有了looper且已启动,意味着包含了消息队列。
所有没有指定looper对象而创建的handler,使用的都是main的looper。
这样的handler发送的message都放到了main线程的looper管理的消息队列中了。
发现有HandlerThread这个类,以前没用过,总以为是在Thread中内置了一个Handler。
在面试中也总是被问到,很心烦,于是索性来研究一下,正好前面也整体分析了looper,handler等技术。
先来看下源码吧:
/** * 创建一个新的线程类,同时包含有一个Looper. 然后可以使用这个Looper创建一个Handler. * Note:包含有一个Looper意味着什么? * 启动线程时启动looper消息循环,looper内置有messageQueue。这个线程专用来处理消息的了 * 看文章:Android多线程消息处理机制,http://blog.csdn.net/fesdgasdgasdg/article/details/52081773 */public class HandlerThread extends Thread { int mPriority;//线程优先级 int mTid = -1;//进程id Looper mLooper;//核心对象 public HandlerThread(String name) { super(name);//获取线程默认的优先级,0 mPriority = Process.THREAD_PRIORITY_DEFAULT; } /** * 构造函数 * @param name 线程名称 * @param priority 线程优先级. 必须从android.os.Process获取,而不能从java.lang.Thread获取. */ public HandlerThread(String name, int priority) { super(name); mPriority = priority; } /** * 如果需要在looper循环前执行一些操作时,可以显式的重写此方法 */ protected void onLooperPrepared() { }/** * 线程的run方法,在线程start()后,就开始执行run方法, * 在run里面Looper.prepare()创建looper... * 此内容参考:Android多线程消息处理机制,http://blog.csdn.net/fesdgasdgasdg/article/details/52081773 */ @Override public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared();//循环前的回调 Looper.loop(); mTid = -1; } /** * 此方法返回当前线程关联的looper, * 如果当前线程没有启动或者已停止等原因,此方法返回null * 如果此方法已经启动,此方法将阻塞知道looper被初始化 * @return The looper. */ public Looper getLooper() { //如果当前线程不处在运行状态,则返回null if (!isAlive()) { return null; } // 如果此方法已经启动,此方法将阻塞知道looper被初始化 synchronized (this) { while (isAlive() && mLooper == null) { try { wait(); } catch (InterruptedException e) { } } } return mLooper; } /** * 退出线程的looper循环. * 使looper线程终止消息循环,不再处理消息队列中的任何消息 * 当looper调用quit之后,任何尝试post message到messageQueue中的操作都会失败 * 比喻:Handler的sendMessage(Message)方法会返回false * 使用这个方法可能不安全,因为在looper停止之前可能有message没有被执行。 * 考虑使用quitSafely()方法代替quit()方法,以确保所有待完成的工作有序完成。 * @return 如果looper调用了quit,则返回true。如果线程还没有开始执行则返回false * * @see #安全退出 */ public boolean quit() { Looper looper = getLooper();//获取当前线程的looper if (looper != null) { looper.quit(); return true;//成功的调用了quit,返回true } return false; } /** * 安全的退出线程looper循环。 * 当messageQueue中所有已到期的message都处理完后,终止looper线程的消息循环。 * 但是由于延时的消息需要等待,故这些消息将不会被处理。 * Pending delayed messages with due times in the future will not be delivered. * 当looper调用quit之后,任何尝试post message到messageQueue中的操作都会失败 * 比喻:Handler的sendMessage(Message)方法会返回false * 如果线程没有被启动,或者已经结束则返回false。否则在调用quitSafely()之后返回true。 */ public boolean quitSafely() { Looper looper = getLooper(); if (looper != null) { looper.quitSafely(); return true; } return false; } /** * 返回此线程的标识符. 参考Process.myTid(). */ public int getThreadId() { return mTid; }}
这么一分析,是否都清楚了?无非就是个Thread,在里面内置了一个Looper,looper会自带一个MessageQueue。
在Thread的run方法中使用looper.prepqre()创建了looper。然后赋给当前线程的looper成员变量,供外面的handler使用。
接着调用looper.loop()方法启动消息循环。
前面也讲过可以自己创建LooperThread线程,HandlerThread就是google提供的经典实例,只不过HandlerThread里面提供了线程安全访问,退出消息循环等方法。
具体的用法简单的1C, 下面就用自己创建的LooperThread为例,如果你不喜欢的话,直接把LooperThread替换成现有的HandlerThread类即可。
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Handler mHandler; private LooperThread thread; private TextView show; private Button start; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); show = (TextView) findViewById(R.id.show); start = (Button) findViewById(R.id.start); start.setOnClickListener(this); init(); } private void init() { thread = new LooperThread(); thread.start(); while (thread.getLooper() == null) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } mHandler = new Handler(thread.getLooper()) { @Override public void handleMessage(Message msg) { //处理消息 Log.v("looper的handler", Thread.currentThread().getName() + " - " + msg.what); //修改textview会报错的。 //show.setText(""); } }; } @Override public void onClick(View v) { mHandler.sendEmptyMessage(200); } /** * Looper线程 */ class LooperThread extends Thread { private Looper looper; public Looper getLooper() { return looper; } @Override public void run() { super.run(); Looper.prepare(); looper = Looper.myLooper(); Looper.loop(); } }}
初始化的时候先创建LooperThread线程,且启动。
然后里面就会有looper了。
在创建handler的时候传入上面的looper。那么此时的handler已和LooperThread的消息队列绑定了。这个handler所发送和处理的消息只经过LooperThread的消息循环,
跟UI线程已有的消息循环没关系了。
最后有一点需要注意:
public void handleMessage(Message msg) { //处理消息 Log.v("looper的handler", Thread.currentThread().getName() + " - " + msg.what); //修改textview会报错的。 //show.setText(""); }
这个处理消息的方法,不能再处理UI线程创建的UI控件了。如果你真心想修改某一个ui,那的保证这个ui必须在LooperThread里面创建和添加到window中去。
不多说了,该去关心下宝宝。
2 1
- Android多线程消息处理机制 HandlerThread案例分析
- Android-异步消息处理机制2以及HandlerThread的介绍
- Android-异步消息处理机制2 -HandlerThread的介绍
- Android多线程消息处理机制(三) Handler部分源码分析
- Android Handler,Loop,HandlerThread消息处理
- 解析Android消息处理机制 ——HandlerThread/Looper & MessageQueue & Message
- HandlerThread、Loop、MessageQueue、Handler、Message组成的Android的消息处理机制
- android应用程序消息处理机制分析之消息处理
- Android应用程序消息处理机制Handler分析
- Android消息处理机制(源码分析为主)
- Android的消息处理机制源码分析
- android异步处理,分析Handle消息机制
- android应用消息处理机制分析之消息循环
- Android HandlerThread 消息循环机制之源码解析
- Android多线程,异步消息处理机制, Thread, AsyncTask 简单总结
- Android多线程----异步消息处理机制之Handler
- Android多线程----异步消息处理机制之Handler详解
- Android多线程消息处理机制(一) Looper、Thread专题
- 搭建PHP+Apahce+window7环境,和Cannot load c:/php/php5apache2_4.dll into server问题的解决
- bzoj1085: [SCOI2005]骑士精神
- JAVA中public private protected和默认的区别
- C语言基本教程 第12课:文件输入输出(IO)
- akka应用背景介绍
- Android多线程消息处理机制 HandlerThread案例分析
- 二维码制作-js客户端与java服务器端两种
- CSS Transform / Transition / Animation 属性的区别
- 黑马Android:电话拨号器
- Android 每周必看资源
- 用webstorm在chrome 调试页面时一直弹出说页面未经授权。
- java 的 equals()方法
- AIDL的学习记录
- 金额转换,阿拉伯数字的金额转换成中国传统大写汉字的形式