Android之HandlerThread
HandlerThread详解
1 HandlerThread基本原理
HandlerThread继承自Thread,它是一种可以使用Handler的Thread。它的实现很简单,就是在run方法中通过Looper.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环。这样,我们就可以直接在HandlerThread中创建Handler了。HandlerThread的run方法如下所示:
1 public void run() { 2 mTid = Process.myTid(); 3 Looper.prepare(); 4 synchronized (this) { 5 mLooper = Looper.myLooper(); 6 notifyAll(); 7 } 8 Process.setThreadPriority(mPriority); 9 onLooperPrepared(); 10 Looper.loop(); 11 mTid = -1; 12 }
既然HandlerThread中已经有了消息循环,那么我们就可以在HandlerThread类或其子类中直接创建Handler对象,但是我们要记住一点:如果我们需要创建与该HandlerThread线程相关联的Handler的话,我们要使用Handler(Looper looper)构造方法,这样我们所创建的Handler对象才会与当前线程的消息循环相关联。在HandlerThread中,我们可以通过getLooper()方法获得Looper实例。
从HandlerThread的实现上来看,它和普通Thread有显著不同,普通Thread主要在run方法中执行耗时任务,而HandlerThread在内部创建了消息队列,外界需要通过Handler的消息方式来通知HandlerThread执行一个具体任务。通常,一个普通的Thread线程也可以成为Looper线程,我们只需要为其创建消息队列并开启消息循环即可。看如下实现代码:
class LooperThread extends Thread {public Handler mHandler;public void run() {Looper.prepare();mHandler = new Handler() {public void handleMessage(Message msg) {// process incoming messages here }};Looper.loop();} }
我们可以根据不同应用场景选择不同的实现方式,不过既然Android已经提供了HandlerThread类,那我们在开发过程中可能会更倾向于使用该类完成耗时操作。
2 示例程序
我们将通过一个简单示例程序来说明HandlerThread的用法。本示例程序中,我们向HandlerThread发送消息,然后HandlerThread返回该消息并显示到TextView上,在这个过程中我们通过sleep来模拟耗时操作。我们将创建一个继承自HandlerThread的类:CustomHandlerThread,
1 public class CustomHandlerThread extends HandlerThread { 2 private static final String TAG = "CustomHandlerThread"; 3 private static final int MSG_WHAT = 0x11; 4 private Handler mResponseHandler; 5 private Handler mHandler; 6 private Callback mCallback; 7 public CustomHandlerThread(Handler responseHandler, Callback callback){ 8 super(TAG); 9 mHandler = new Handler(); 10 mResponseHandler = responseHandler; 11 mCallback = callback; 12 } 13 14 public void enqueTask(String str, TextView textView){ 15 Log.i(TAG, "receive a str: " + str); 16 mHandler.obtainMessage(MSG_WHAT, str).sendToTarget(); 17 } 18 public void prepareHandler(){ 19 mHandler = new Handler(getLooper()){ 20 @Override 21 public void handleMessage(final Message msg) { 22 try{ 23 TimeUnit.SECONDS.sleep(2); 24 final String result = (String)msg.obj; 25 mResponseHandler.post(new Runnable() { 26 @Override 27 public void run() { 28 mCallback.onResult(result); 29 } 30 }); 31 }catch (InterruptedException ie){ 32 ie.printStackTrace(); 33 } 34 } 35 }; 36 } 37 38 public interface Callback{ 39 public void onResult(String result); 40 } 41 public void removeMsg(){ 42 mHandler.removeMessages(MSG_WHAT); 43 } 44 45 }
我们先看enqueTask方法,该方法很简单,我们仅用它来接收从外部传来的参数(准确的说是消息内容),并且通过当前线程的Handler将消息发送到当前线程消息队列中,对该消息的处理是在prepareHandler()方法中完成的。在prepareHandler方法中,我们创建Handler实例,并且与当前线程的消息队列相关联,这通过Handler(Looper looper)构造方法完成。mResponseHandler.post方法会将Runnable对象添加到主线程的消息队列,该Runnable对象将会在该mResponseHandler所属的线程中执行,由于mResponseHandler是从主线程传过来的(稍后我们会看到具体实现),因此Runnable将会运行在主线程中。run方法中我们通过回调接口来传递结果。下面我们看下MainActivity中的处理:
1 public class MainActivity extends Activity implements CustomHandlerThread.Callback{ 2 private TextView mTextView; 3 4 private CustomHandlerThread mCustomHandlerThread; 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 setContentView(R.layout.activity_main); 9 mTextView = (TextView)findViewById(R.id.textView); 10 11 mCustomHandlerThread = new CustomHandlerThread(new Handler(), this); 12 mCustomHandlerThread.start(); 13 mCustomHandlerThread.prepareHandler(); 14 for(int i = 0; i < 10; i++){ 15 mCustomHandlerThread.enqueTask("string"+i); 16 } 17 } 18 19 @Override 20 public void onResult(String result) { 21 mTextView.setText(result); 22 } 23 24 @Override 25 protected void onDestroy() { 26 super.onDestroy(); 27 mCustomHandlerThread.removeMsg(); 28 mCustomHandlerThread.quit(); 29 } 30 }
上面代码很简单,我们创建CustomHandlerThread并传入Handler对象,该Handler对象是在主线程中创建的,因此与主线程消息队列相关联,创建HandlerThread对象后必须要调用start方法,此外,在调用enqueTask之前必须先调用prepareHandler方法,以免导致空指针异常(Handler还没创建?怎么能向消息队列发送消息呢?)。最后要注意的是,当Activity退出时,我们一定要通过quit方法结束HandlerThread的执行。
转载于:https://www.cnblogs.com/e007/p/6272922.html
Android之HandlerThread相关推荐
- Android之HandlerThread源码分析和简单使用(主线程和子线程通信、子线程和子线程通信)
1.先熟悉handler方式实现主线程和子线程互相通信方式,子线程和子线程的通信方式 如果不熟悉或者忘记了,请参考我的这篇博客 Android之用Handler实现主线程和子线程互相通信以及子 ...
- 【Android】HandlerThread详解
之前总结过Android Handler.Looper.Message.MQ的知识点,我们翻看源码的时候,看到一个关键类HandlerThread,当时还提出过疑问,这个和Thread有什么区别.本节 ...
- Android之使用HandlerThread 以及如何退出总结
1 .使用 HandlerThread handlerThread = new HandlerThread("handlerThread"); handlerThread.star ...
- Android中文API(128) —— HandlerThread
前言 本章内容是android.os.HandlerThread,版本为Android 3.1 r1,翻译来自"雪鹰工作室",再次感谢"雪鹰工作室"!欢迎你一起 ...
- Android 多线程之HandlerThread 完全详解
转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52426353 出自[zejian的博客] 关联文章: Android ...
- java handlerthread_深入Android HandlerThread 使用及其源码完全解析
本篇我们将来给大家介绍HandlerThread这个类,以前我们在使用线程执行一个耗时任务时总会new一个Thread的线程去跑,当任务执行完后,线程就会自动被销毁掉,如果又由新的任务,我们又得新建线 ...
- Android HandlerThread例程
在多线程通信中我们通常使用handler进行异步通信.在线程中使用handler稍微有一些麻烦,比如说创建handler的时候必须保证当前线程中有Looper对象,否则会创建失败. 安卓的主线程自带一 ...
- Android中Handler
本文通过例子来验证和说明使用Handler对象开启的线程是否和主线程为在同一线程中. 程序结构图如下: [1] HandlerActivity.java中的源码如下: [html] view plai ...
- android webview java_Android Webview中调用本地java方法
在网页调用本地的分享SDK class JsObject { @JavascriptInterface public String toString() { return "injected ...
- Android中的Handler
当我们在处理下载或是其它须要长时间运行的任务时.假设直接把处理函数放在Activity的OnCreate或是OnStart中.会导致运行过程中整个Activity无响应,假设时间过长,程序就会挂掉. ...
最新文章
- cv_bridge中的编码模式与实现
- GLSL实现滤镜效果
- NFV和VNF的现状如何
- nginx和php之间是怎样通信的呢(简答)
- Jmter操作数据库
- php memcache 扩展 libmemcached 安装
- 浅谈ES6中的rest参数
- DB2 表的常用命令
- Android UI学习之SeekBar
- 基于ABAQUS蠕变储层稠油蒸汽吞吐开发过程数值模拟
- 关于电瓶车管理的思考
- snmpwalk与snmpget的区别
- cad化工设备绘图_化工CAD制图基础篇,管道布置图学起来
- 计算机考研复试C语言常见面试题
- 阿里云服务器续费流程方法(图文详解)
- 猿来小课Java视频教程讲师浅谈JAVA体系结构
- 3DMAX输入序列后消失/闪退问题解决方案
- 头歌--CC++函数实训
- 液晶屏的Dithering功能
- 碧桂园博智林机器人总部大楼_碧桂园的800亿机器人梦,碎了?
热门文章
- 解决cdh4.5.0下 MAP任务看不到状态
- Eval()、XPath() 和 Bind() 这类数据绑定方法只能在数据绑定控件的上下文中使用
- linux那些鲜为人知的小秘密
- Mac上设置图片或视频的默认打开软件的方法
- Arturia系列合成器插件大合集:Arturia V Collection 8 for mac
- 微信小程序 数据绑定
- 巧用EasyRecovery监控硬盘 为你的电脑保驾护航
- EasyRecovery,拯救那些遗失的文件
- Check $M2_HOME environment variable and mvn script
- SpringBoot非官方教程 | 第二十二篇: 创建含有多module的springboot工程