Android HandlerThread案例详解
作者:tandeneck 时间:2022-04-20 09:46:25
HandlerThread 顾名思义就是一种可以使用 Handler 的 Thread。日常开发中我们经常会通过创建一个 Thread 去执行任务,有多个任务就多创建几个线程实现,这时候可能出现线程同步的问题。不过有时候我们并不需要很强的并发性,只需保证按照顺序地执行各个任务即可,有什么好办法实现呢?第一反应想到的可能是通过 Executors.newSingleThreadExecutor() 方法来创建一个 SingleThreadExecutor,来统一所有的任务到一个线程中,然后按顺序执行。其实,除了这个方法之外,HandlerThread 也可以实现。
简单使用
首先创建一个 HandlerThreadActivity
public class HandlerThreadActivity extends BaseActivity {
private static final String TAG = "HandlerThreadActivity";
private Button mStartBtn;
private Handler mHandler;
private HandlerThread mHandlerThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_thread);
mStartBtn = findViewById(R.id.start_btn);
mHandlerThread = new HandlerThread("THREAD_NAME");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mStartBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mHandler.post(new Runnable() {
@Override
public void run() {
Log.d(TAG, Thread.currentThread().getId() + " " + String.valueOf((Looper.myLooper() == Looper.getMainLooper())) + " 任务:" + this.hashCode());
SystemClock.sleep(3000);
}
});
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandlerThread.quit();
}
}
快速三击按钮,打印日志如下:
可以发现,三次不同的任务按开始的顺序执行,而且是运行在子线程中,那到底是怎么实现的呢?
源码解析
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
private @Nullable Handler mHandler;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
protected void onLooperPrepared() {
}
@Override
public void run() {
// 获取线程 id
mTid = Process.myTid();
//构建一个 Looper
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
//设置线程优先级
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
// Looper 循环
mTid = -1;
}
// 获取当前线程的 Looper,
public Looper getLooper() {
if (!isAlive()) {
return null;
}
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
/**
* @return a shared {@link Handler} associated with this thread
* @hide 方法隐藏掉,无法调用
*/
@NonNull
public Handler getThreadHandler() {
if (mHandler == null) {
mHandler = new Handler(getLooper());
}
return mHandler;
}
//线程退出方法,主要是调用 Looper.quit() 方法,不然一直在循环
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;
}
public int getThreadId() {
return mTid;
}
}
通读下来,如果熟悉 Handler 原理的同学大概就明白 HandlerThread 的机制了:
HandlerThread 运行 start() 方法,回调 run() 方法。
在 run() 方法中通过 Looper.prepare() 来创建消息队列,并通过 Looper.looper() 方法来开启消息循环。
由于 Loop.loop() 是一个死循环,导致 run() 也是无线循环,因此当我们不需要使用 HandlerThread 的时候,要调用它的 quit() 方法或者 quiteSafely() 方法。
来源:https://www.jianshu.com/p/9807338a38c3
标签:Android,HandlerThread
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Java编程基本概念
2023-09-07 07:15:50
Java实现矩阵加减乘除及转制等运算功能示例
2023-07-05 04:49:53
![](https://img.aspxhome.com/file/2023/0/64050_0s.png)
解析SpringBoot中使用LoadTimeWeaving技术实现AOP功能
2023-04-19 00:21:47
![](https://img.aspxhome.com/file/2023/1/69671_0s.jpg)
java后台利用Apache poi 生成excel文档提供前台下载示例
2023-05-15 08:51:45
![](https://img.aspxhome.com/file/2023/9/75749_0s.jpg)
Hadoop1.2中配置伪分布式的实例
2023-01-26 12:20:56
SpringBoot打jar包遇到的xml文件丢失的解决方案
2023-04-11 23:39:06
![](https://img.aspxhome.com/file/2023/4/66174_0s.png)
Java 中普通代码块,构造代码块,静态代码块区别及代码示例
2022-07-03 03:54:21
java实现科研信息管理系统
2022-05-13 02:49:41
![](https://img.aspxhome.com/file/2023/9/67009_0s.jpg)
C语言与C++中关于字符串使用的比较
2022-01-22 01:30:37
java发送get请求和post请求示例
2022-01-30 10:45:52
Java之JFrame输出Helloworld实例
2022-01-19 16:40:52
![](https://img.aspxhome.com/file/2023/5/71185_0s.png)
微信小程序获取手机号,后端JAVA解密流程代码
2023-11-29 07:57:26
C# ListBox中的Item拖拽代码分享
2022-04-12 14:06:41
![](https://img.aspxhome.com/file/2023/7/94577_0s.gif)
详解JAVA Spring 中的事件机制
2022-01-13 05:26:33
Mybatis代码生成器Mybatis Generator(MBG)实战详解
2023-12-02 23:04:31
![](https://img.aspxhome.com/file/2023/1/73031_0s.jpg)
Java远程连接Linux服务器并执行命令及上传文件功能
2023-01-28 14:03:31
SpringBoot如何通过Feign调用传递Header中参数
2023-11-24 21:39:29
C#实现加密的几种方法介绍
2022-12-12 22:38:00
Spring Boot 整合 Apache Dubbo的示例代码
2021-10-09 03:52:07
![](https://img.aspxhome.com/file/2023/8/60488_0s.jpg)
23种设计模式(19)java责任链模式
2021-10-19 15:04:00
![](https://img.aspxhome.com/file/2023/7/89487_0s.jpg)