Android的消息机制中,如果需要在子线程中创建Hanlder来处理消息,那么很经典的代码如下:

new Thread(new Runnable() {@Overridepublic void run() {Looper.prepare();handler = new Handler(Looper.myLooper()){@Overridepublic void handleMessage(@NonNull Message msg) {}};Looper.loop();}
}).start

这样处理比较繁琐,有点类似于Service中的意图服务的意思。因为自己创建比较繁琐,故而官方就提供了一套封装。

回顾一下:使用意图服务的时候,只需要自定义一个继承自IntentService的类,复写onHandleIntent方法即可,然后可在该方法中进行耗时操作,且操作完成后自动销毁Service

那么在使用HandlerThread的时候,应该如何?

HandlerThread 是一个包含 LooperThread,我们可以直接使用这个 Looper 创建 Handler

HandlerThread 所做的就是在新开的子线程中创建了 Looper,那它的使用场景就是 前面提到的需要在子线程中创建Handler,来处理消息的场景。

这里不妨看下这个类的构成:

public class HandlerThread extends Thread {int mPriority;int mTid = -1;Looper mLooper;private @Nullable Handler mHandler;...public void run() {mTid = Process.myTid();Looper.prepare();synchronized (this) {mLooper = Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid = -1;}public Handler getThreadHandler() {if (mHandler == null) {mHandler = new Handler(getLooper());}return mHandler;}
}

在上面可以看见HandlerThread是一个线程类,且在run方法中初始化了对应的Looper对象,在getThreadHandler方法中创建一个和Looper关联的Handler对象。

那么,我们在使用的时候应该如何使用?不妨看看下面的简单案例:

public class MainActivity extends AppCompatActivity {private Handler workHandler;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button button = findViewById(R.id.id_mybutton);// 【开启子线程】开启一个子线程来处理消息  Looper+Thread+HandlerHandlerThread handlerThread = new HandlerThread("MyHandlerThread");handlerThread.start();workHandler = new Handler(handlerThread.getLooper()){@Overridepublic void handleMessage(@NonNull Message msg) { // 【子线程处理消息】String channelId = "weizu";// 1. 创建通知管理器NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);// 2. 创建通道NotificationChannel channel = new NotificationChannel(channelId,"Simple Test", NotificationManager.IMPORTANCE_DEFAULT);manager.createNotificationChannel(channel);// 3. 创建通知对象Notification.Builder builder = new Notification.Builder(MainActivity.this, channelId);Intent intent = new Intent(getApplicationContext(), MainActivity.class);PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);Notification notification = builder.setContentTitle("Info").setContentText((String) msg.obj).setContentIntent(pi).setSmallIcon(R.drawable.ic_baseline_bluetooth_24).setAutoCancel(true).build();// 4. 发送通知manager.notify(1, notification);}};button.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 【主线程】点击事件来发送消息Message msg = Message.obtain();msg.what = 1;msg.obj = "Hello";workHandler.sendMessage(msg);}});}
}

在上面的结果中,我们在子线程HandlerThread中也可以在状态栏显示通知,进行了消息的处理。

需要注意的是,子线程中不可进行更新UI操作,显然,这里的Notification不属于更新UI操作。

注意到在run中调用了Looper.loop方法,故而是一个无限循环。

也就是说这个HandlerThread方法不会自动停止,我们需要显示的调用quit方法,当不需要的时候,可以结束线程,即workHandler.quit();


另在IntentService类中也有HandlerThread的影子:

public abstract class IntentService extends Service {private volatile Looper mServiceLooper;private volatile ServiceHandler mServiceHandler;private final class ServiceHandler extends Handler {public ServiceHandler(Looper looper) {super(looper);}@Overridepublic void handleMessage(Message msg) {onHandleIntent((Intent)msg.obj);stopSelf(msg.arg1);}}...public void onCreate() {super.onCreate();HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");thread.start();mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper);}

在个方法中类似的关联了Looper对象、Handler对象,以及前面提到的HandlerThread线程对象。且在onCreate周期函数中的使用方式和我们的案例中类似。

HandlerThread案例学习相关推荐

  1. 通过脚本案例学习shell(五) 通过创建DNS脚本一步一步教你将一个普通脚本规范到一个生产环境脚本...

    通过脚本案例学习shell(五) 通过创建DNS脚本一步一步教你将一个普通脚本规范到一个生产环境脚本   版权声明: 本文遵循"署名非商业性使用相同方式共享 2.5 中国大陆"协议 ...

  2. 《大数据导论》——1.4节案例学习背景

    本节书摘来自华章社区<大数据导论>一书中的第1章,第1.4节案例学习背景,作者瓦吉德·哈塔克(Wajid Khattak),保罗·布勒(Paul Buhler),更多章节内容可以访问云栖社 ...

  3. ArcGIS案例学习1_2

    ArcGIS案例学习1_2 联系方式:向日葵,135_4855_4328, xiexiaokui#qq.com 时间:第一天下午 案例1:矢量提取,栅格提取和坐标系投影变换 目的:认识数据类型 教程: ...

  4. 零元学Expression Blend 4 ndash; Chapter 21 以实作案例学习MouseDragElementBehavior

    原文:零元学Expression Blend 4 – Chapter 21 以实作案例学习MouseDragElementBehavior 本章将教大家如何运用Blend 4内建的行为注入元件「Mou ...

  5. ArcGIS案例学习笔记-找出最近距离的垂线

    ArcGIS案例学习笔记-找出最近距离的垂线 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 目的:对于任意矢量要素类,查找最近距离并做图 数据: 方法: 0. 计算 ...

  6. ArcGIS案例学习笔记2_2_等高线生成DEM和三维景观动画

    ArcGIS案例学习笔记2_2_等高线生成DEM和三维景观动画 计划时间:第二天下午 教程:Pdf/405 数据:ch9/ex3 方法: 1. 创建DEM SA工具箱/插值分析/地形转栅格 2. 生成 ...

  7. 案例学习BlazeDS+Spring之一(

    BlazeDS4的一个亮点就是与Spring的集成,这大大简化了与FLASH与JEE的集成开发.通过理解BlazeDS4附带的那些精湛的小DEMO,可以很快速的掌握这门技术.虽然案例学习这种方式不太利 ...

  8. 《大数据导论》一1.4 案例学习背景

    本节书摘来自华章出版社<大数据导论>一书中的第1章,第1.4节,作者托马斯·埃尔(Thomas Erl),瓦吉德·哈塔克(Wajid Khattak),保罗·布勒(Paul Buhler) ...

  9. ArcGIS模型构建器案例学习笔记-字段处理模型集

    ArcGIS模型构建器案例学习笔记-字段处理模型集 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 由四个子模型组成 子模型1:判断字段是否存在 方法:python工 ...

最新文章

  1. 微软开源的自动机器学习工具上新了:NNI概览及新功能详解
  2. Windows10 + VS2015 (Win SDK10)环境下的64位 VTK编译小结
  3. JDBC批量操作批量增加批量修改
  4. mysql的innodb如何定位锁问题_mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?...
  5. 8 计算机组成原理第五章 中央处理器 控制器 硬布线控制器 微程序控制器
  6. python可以给你干什么-Python到底可以做什么?
  7. linux 百度云 备份软件下载,百度云存储api实现文件分享及linux下的备份上传
  8. 机器学习鸢尾花数据集分析
  9. 关联本地项目和svn_SVN服务器项目如何与本地项目同步,关联?
  10. 什么是网站跳出率?一招教你如何处理高跳出率?
  11. 数据分析—指标体系和报表
  12. android系统美化app,手机主题App哪个好用?安卓手机主题App推荐
  13. 深入浅出计算机原理组成--->指令与运算——指令跳转(2)
  14. 叫板SharePoint,多可致力打造满足中国企业需要的文档管理软件
  15. Android如何制作.9图片
  16. python如何设置rgb颜色_Python 转换RGB颜色值的示例代码
  17. 常微分方程(Ordinary differential equation)
  18. 电容充电时间计算公式
  19. 数电快速入门(二)(复合逻辑运算和逻辑代数的基本定律的介绍)
  20. 计算机二级如何准备(附资料和题库)

热门文章

  1. 使用Vitis固化程序
  2. 巧用 Curl 命令测试 Unix Socket 接口
  3. 基于Python的车牌检测和识别系统
  4. 3. 使用xUnit进行单元测试
  5. JAVA山地车deca_JAVA 2020 款山地车盘点
  6. linux c 读取mat文件格式,MAT 文件扩展名: 它是什么以及如何打开它?
  7. MySQL 之 lpad,rpad 函数用法
  8. Jmeter进行http接口测试,这一篇就搞定
  9. 离谱!结论相反的两篇论文共用同一张图,教授:可能是研究生的错
  10. kali2.0 2016.2 宽带拨号上网