安卓开发面试题(9/30)HandlerThread全解析
牛客高级系列专栏:
安卓(安卓系统开发也要掌握)
- 想通关安卓面试,请看(承诺免费售后答疑):《150道安卓高频面试题目录及答案链接》
- 想通关安卓系统面试,请看:《140道安卓系统Framework面试题目录及答案链接》
- 想进阶安卓开发,请看(承诺免费售后答疑):《Android进阶知识体系解析_15大安卓进阶必备知识点》
- 想了解安卓APP完整开发流程,请看(承诺免费售后答疑):《安卓APP完整开发流程》
- 想掌握安卓App性能优化,请看(承诺免费售后答疑):《安卓性能优化讲解和实战专栏》
- 想掌握Gradle语法和配置,制作Gradle插件,请看(承诺免费售后答疑):《安卓Gradle语法解析和实践大全》
嵌入式
- 想通关嵌入式面试,请看: 《111道嵌入式面试题目录及答案链接》
- 想多掌握几个嵌入式项目,请看:《6个嵌入式项目交流分享(附源码)》
本人是2020年毕业于广东工业大学研究生:许乔丹,有国内大厂CVTE和世界500强企业安卓开发经验,该专栏整理本人对常见安卓高频开发面试题的理解;
网上安卓资料千千万,笔者将继续维护专栏,一杯奶茶价格不止提供答案解析,承诺提供专栏内容免费技术答疑,直接咨询即可。助您提高安卓面试准备效率,为您面试保驾护航!
正文开始⬇
Handler异步消息处理机制是安卓面试的最常见内容之一,面试完问完Handler后可能来一句:“你了解HandlerThread”吗?此时如果能说上几句,一定可以给自己加分。面试官可能会问:
- HandlerThread是什么?⭐⭐⭐⭐⭐
- HandlerThread原理和使用场景?⭐⭐⭐⭐
看完以下的解析,一定可以让面试官眼前一亮。
目录
- 1、HandlerThread是什么?
- 2、HandlerThread怎么使用
- 3、源码分析
- 4、总结
1、HandlerThread是什么?
在安卓开发中,如果需要执行耗时操作,则可以开启子线程来完成,然而手动创建销毁线程又麻烦又消耗系统性能,因此可以使用线程池来完成。如果还需要在线程中使用Handler异步消息机制,或者需要实现子线程和子线程之间的通讯(Handler是主线程和子线程之间的通讯),那么就可以用HandlerThreaad。
HandlerThread是Google封装好的一个类,它的内部有自己的Looper对象,可以进行Loop轮询,用于执行多个耗时操作,而不需要多次开启线程,本质是使用Handler和Looper实现的。
2、HandlerThread怎么使用
如果我们需要使用HandlerThread来读取一个大文件的内容,可以这么写:
public class Xuruictivity extends AppCompatActivity {
private static final int MSG_READ_INFO = 100;
Handler mMainHandler = new Handler();
private Handler mThreadHandler;
private HandlerThread mHandlerThread;
private boolean isFinish = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_xurui);
initHandlerThread(); //1
startHandlerThread();
}
private void initHandlerThread() {
mHandlerThread = new HandlerThread("Xurui"); //2
mHandlerThread.start(); //3
mThreadHandler = new Handler(mHandlerThread.getLooper()) { //4
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_READ_INFO: {
readFileInfo();
// 如果没有读完,则继续
if (!isFinish) {
mThreadHandler.sendEmptyMessage(MSG_READ_INFO);
}
}
break;
default:
break;
}
}
};
}
/**
* 模拟读取文件
*/
private void readFileInfo() {
try {
//模拟耗时
Thread.sleep(1200);
mMainHandler.post(new Runnable() {
@Override
public void run() {
// 读取大文件内容
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void startHandlerThread() {
mThreadHandler.sendEmptyMessage(MSG_READ_INFO);
}
@Override
protected void onPause() {
super.onPause();
mThreadHandler.removeMessages(MSG_READ_INFO); //5
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandlerThread.quit();//6
mMainHandler.removeCallbacksAndMessages(null); //7
}
}
使用mHandlerThread的looper创建的mThreadHandler,对应注释4,里面的handleMessage是可以进行耗时操作的,因为它是执行在mHandlerThread所在的子线程。因此其优点是不会阻塞主线程,但是多任务时也需要有序执行,导致执行效率低。因此HandlerThread比较适合耗时不且不会产生较大的阻塞,比如读取文件,操作数据库等,至于网络IO操作这种可能有较大阻塞等,HandlerThread并不适合。
上面代码最关键的步骤都在注释1的函数里。我们来看看HandlerThread的使用方法:
- 创建HandlerThread实例:对应注释2,其中“xurui”是子线程的名字,可以随意取;
- 执行start函数来启动HandlerThread线程:对应注释3;
- 将HandlerThread和Handler绑定:对应注释4;
- 然后执行startHandlerThread()就行了,最后记得退出HandlerThread,对应注释6。
为何是这样的步骤,那就进入激动人心的源码分析吧!
3、源码分析
HandlerThread的源码仅仅100+行,因此直接copy完整的源码,不做任何删减(下面源码是android9.0.0的源码)。
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
private @Nullable Handler mHandler;
public HandlerThread(String name) { //1
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
/**
* Constructs a HandlerThread.
* @param name
* @param priority The priority to run the thread at. The value supplied must be from
* {@link android.os.Process} and not from java.lang.Thread.
*/
public HandlerThread(String name, int priority) { //2
super(name);
mPriority = priority;
}
/**
* Call back method that can be explicitly overridden if needed to execute some
* setup befo
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
#提供免费售后答疑!!花一杯奶茶的钱获得安卓面试答疑服务,稳赚不赔# Android发展已经很多年,安卓资料网上千千万,本专栏免费提供专栏内容技术答疑!!私聊当天必回。在阅读过程或者其他安卓学习过程有疑问,都非常欢迎私聊交流。

