1.简介
AndroidThread是一个Android已经封装好的轻量级异步类,用来方便开发者更快的实现多线程、异步通信、消息传递等。
2.使用步骤
// 步骤1:创建HandlerThread实例对象
// 传入参数 = 线程名字,作用 = 标记该线程
HandlerThread mHandlerThread = new HandlerThread("handlerThread");
// 步骤2:启动线程
mHandlerThread.start();
// 步骤3:创建工作线程Handler & 复写handleMessage()
// 作用:关联HandlerThread的Looper对象、实现消息处理操作 & 与其他线程进行通信
// 注:消息处理操作(HandlerMessage())的执行线程 = mHandlerThread所创建的工作线程中执行
Handler workHandler = new Handler( mHandlerThread.getLooper() ) {
@Override
public boolean handleMessage(Message msg) {
...//消息处理
return true;
}
});
// 步骤4:使用工作线程Handler向工作线程的消息队列发送消息
// 在工作线程中,当消息循环时取出对应消息 & 在工作线程执行相关操作
// a. 定义要发送的消息
Message msg = Message.obtain();
msg.what = 2; //消息的标识
msg.obj = "B"; // 消息的存放
// b. 通过Handler发送消息到其绑定的消息队列
workHandler.sendMessage(msg);
// 步骤5:结束线程,即停止线程的消息循环
mHandlerThread.quit();
3.与普通线程的对比
如果在Thread里使用Handler,我们要调用Looper.prepare() 和Looper.loop()
// 子线程中创建新的Handler 没有使用HandlerThread
new Thread () {
@Override
public void run() {
Looper.prepare();
Hnadler handler = new Handler();
Looper.loop();
}
}
而在handlerThread中并没有调用,是因为HandlerThread已经为我们封装好了
HandlerThread源码的run方法
@Override
public void run() {
// 1. 获得当前线程的id
mTid = Process.myTid();
// 2. 创建1个Looper对象 & MessageQueue对象
Looper.prepare();
// 3. 通过持有锁机制来获得当前线程的Looper对象
synchronized (this) {
mLooper = Looper.myLooper();
// 发出通知:当前线程已经创建mLooper对象成功
// 此处主要是通知getLooper()中的wait()
notifyAll();
// 此处使用持有锁机制 + notifyAll() 是为了保证后面获得Looper对象前就已创建好Looper对象
}
// 4. 设置当前线程的优先级
Process.setThreadPriority(mPriority);
// 5. 在线程循环前做一些准备工作 ->>分析1
// 该方法实现体是空的,子类可实现 / 不实现该方法
onLooperPrepared();
// 6. 进行消息循环,即不断从MessageQueue中取消息 & 派发消息
Looper.loop();
mTid = -1;
}
4.具体应用
创建两个Button,分别在工作线程中发送两条不同的消息(实际应用中可能是做了些复杂耗时的操作),然后再主线程中刷新UI(此处用Toast替代)
public class HandlerThreadActivity extends AppCompatActivity {
private Handler mainHandler, workHandler;
private HandlerThread mHandlerThread;
private AppCompatButton mFirstBtn, mSecondBtn;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_thread);
initView();
initHandlerThread();
initHandler();
}
private void initView() {
mFirstBtn = findViewById(R.id.first_btn);
mSecondBtn = findViewById(R.id.second_btn);
}
private void initHandlerThread() {
mHandlerThread = new HandlerThread("GoodLuck");
mHandlerThread.start();
}
private void initHandler() {
//和主线程关联的handler
mainHandler = new Handler();
//工作线程Handler
//作用:关联HandlerThread的Looper对象、实现消息处理操作 & 与其他线程进行通信
// 消息处理操作(HandlerMessage())的执行线程 = mHandlerThread所创建的工作线程中执行
workHandler = new Handler(mHandlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1: {
mainHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(HandlerThreadActivity.this, "我是button1的消息", Toast.LENGTH_SHORT).show();
}
});
break;
}
case 2: {
mainHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(HandlerThreadActivity.this, "我是button2的消息", Toast.LENGTH_SHORT).show();
}
});
break;
}
}
}
};
mFirstBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = Message.obtain();
message.what = 1;
workHandler.sendMessage(message);
}
});
mSecondBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = Message.obtain();
message.what = 2;
workHandler.sendMessage(message);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandlerThread.quit();
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/first_btn"
android:layout_width="match_parent"
android:text="firstBtn"
android:layout_height="48dp"/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/second_btn"
android:text="SecondBtn"
android:layout_width="match_parent"
android:layout_height="48dp"/>
</LinearLayout>