HandlerThread案例学习
在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
是一个包含Looper
的Thread
,我们可以直接使用这个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案例学习相关推荐
- 通过脚本案例学习shell(五) 通过创建DNS脚本一步一步教你将一个普通脚本规范到一个生产环境脚本...
通过脚本案例学习shell(五) 通过创建DNS脚本一步一步教你将一个普通脚本规范到一个生产环境脚本 版权声明: 本文遵循"署名非商业性使用相同方式共享 2.5 中国大陆"协议 ...
- 《大数据导论》——1.4节案例学习背景
本节书摘来自华章社区<大数据导论>一书中的第1章,第1.4节案例学习背景,作者瓦吉德·哈塔克(Wajid Khattak),保罗·布勒(Paul Buhler),更多章节内容可以访问云栖社 ...
- ArcGIS案例学习1_2
ArcGIS案例学习1_2 联系方式:向日葵,135_4855_4328, xiexiaokui#qq.com 时间:第一天下午 案例1:矢量提取,栅格提取和坐标系投影变换 目的:认识数据类型 教程: ...
- 零元学Expression Blend 4 ndash; Chapter 21 以实作案例学习MouseDragElementBehavior
原文:零元学Expression Blend 4 – Chapter 21 以实作案例学习MouseDragElementBehavior 本章将教大家如何运用Blend 4内建的行为注入元件「Mou ...
- ArcGIS案例学习笔记-找出最近距离的垂线
ArcGIS案例学习笔记-找出最近距离的垂线 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 目的:对于任意矢量要素类,查找最近距离并做图 数据: 方法: 0. 计算 ...
- ArcGIS案例学习笔记2_2_等高线生成DEM和三维景观动画
ArcGIS案例学习笔记2_2_等高线生成DEM和三维景观动画 计划时间:第二天下午 教程:Pdf/405 数据:ch9/ex3 方法: 1. 创建DEM SA工具箱/插值分析/地形转栅格 2. 生成 ...
- 案例学习BlazeDS+Spring之一(
BlazeDS4的一个亮点就是与Spring的集成,这大大简化了与FLASH与JEE的集成开发.通过理解BlazeDS4附带的那些精湛的小DEMO,可以很快速的掌握这门技术.虽然案例学习这种方式不太利 ...
- 《大数据导论》一1.4 案例学习背景
本节书摘来自华章出版社<大数据导论>一书中的第1章,第1.4节,作者托马斯·埃尔(Thomas Erl),瓦吉德·哈塔克(Wajid Khattak),保罗·布勒(Paul Buhler) ...
- ArcGIS模型构建器案例学习笔记-字段处理模型集
ArcGIS模型构建器案例学习笔记-字段处理模型集 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 由四个子模型组成 子模型1:判断字段是否存在 方法:python工 ...
最新文章
- 微软开源的自动机器学习工具上新了:NNI概览及新功能详解
- Windows10 + VS2015 (Win SDK10)环境下的64位 VTK编译小结
- JDBC批量操作批量增加批量修改
- mysql的innodb如何定位锁问题_mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?...
- 8 计算机组成原理第五章 中央处理器 控制器 硬布线控制器 微程序控制器
- python可以给你干什么-Python到底可以做什么?
- linux 百度云 备份软件下载,百度云存储api实现文件分享及linux下的备份上传
- 机器学习鸢尾花数据集分析
- 关联本地项目和svn_SVN服务器项目如何与本地项目同步,关联?
- 什么是网站跳出率?一招教你如何处理高跳出率?
- 数据分析—指标体系和报表
- android系统美化app,手机主题App哪个好用?安卓手机主题App推荐
- 深入浅出计算机原理组成--->指令与运算——指令跳转(2)
- 叫板SharePoint,多可致力打造满足中国企业需要的文档管理软件
- Android如何制作.9图片
- python如何设置rgb颜色_Python 转换RGB颜色值的示例代码
- 常微分方程(Ordinary differential equation)
- 电容充电时间计算公式
- 数电快速入门(二)(复合逻辑运算和逻辑代数的基本定律的介绍)
- 计算机二级如何准备(附资料和题库)