根據(jù)Handler創(chuàng)建時(shí)所在的線程不同使用方式也有些不同
一赫舒、在主線程中
示例代碼如下:
public class MainActivity extends AppCompatActivity {
private static final int MSG_1 = 1;
private static final int MSG_2 = 2;
Handler handler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
//在主線程中處理所要進(jìn)行的操作
switch (msg.what) {
case MSG_1:
//TODO 處理相關(guān)問題
Log.i("handler", "MSG_1,當(dāng)前線程名稱:" + Thread.currentThread().getName());
break;
case MSG_2:
//TODO 處理相關(guān)問題
Log.i("handler", "MSG_2双肤,當(dāng)前線程名稱:" + Thread.currentThread().getName());
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendMessage();
postTask();
}
private void sendMessage() {
//從主線程中發(fā)送消息
handler.sendEmptyMessage(MSG_1);
new Thread(new Runnable() {
@Override
public void run() {
//從工作線程中發(fā)送消息
handler.sendEmptyMessage(MSG_2);
}
}).start();
}
private void postTask() {
//主線程中發(fā)送延時(shí)任務(wù)
handler.postDelayed(() -> {
Log.i("handler", "主線程中的postTask杉适,當(dāng)前線程名稱:" + Thread.currentThread().getName());
}, 1000);
new Thread(() -> {
//工作線程中發(fā)送延時(shí)任務(wù)
handler.postDelayed(() -> {
Log.i("handler", "工作線程中的postTask,當(dāng)前線程名稱:" + Thread.currentThread().getName());
}, 1000);
}).start();
}
}
打印日志:
2021-01-07 11:50:25.433 5693-5693/com.example.behaviorapplication I/handler: MSG_1鸟辅,當(dāng)前線程名稱:main
2021-01-07 11:50:25.433 5693-5693/com.example.behaviorapplication I/handler: MSG_2氛什,當(dāng)前線程名稱:main
2021-01-07 11:50:26.400 5693-5693/com.example.behaviorapplication I/handler: 主線程中的postTask,當(dāng)前線程名稱:main
2021-01-07 11:50:26.400 5693-5693/com.example.behaviorapplication I/handler: 工作線程中的postTask匪凉,當(dāng)前線程名稱:main
在主線程中創(chuàng)建的Handler對象枪眉,不管是否從工作線程中發(fā)送消息或任務(wù),所要處理的操作都是在主線程再层。
二贸铜、在工作線程中
示例代碼如下:
public class MainActivity2 extends AppCompatActivity {
private static final int MSG_1 = 1;
private static final int MSG_2 = 2;
Handler threadHandler;
Handler mainHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (threadHandler == null) {
mainHandler.sendEmptyMessageDelayed(1, 1000);
} else {
sendMsg();
postTask();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initThreadHandler();
mainHandler.sendEmptyMessageDelayed(1, 1000);
}
/**
* 在工作線程中創(chuàng)建handler
*/
private void initThreadHandler() {
new Thread(() -> {
//創(chuàng)建當(dāng)前線程的looper,必須在handler創(chuàng)建之前树绩,否則報(bào)錯(cuò)
Looper.prepare();
Log.i("handler", "創(chuàng)建threadHandler萨脑,當(dāng)前線程名稱:" + Thread.currentThread().getName());
threadHandler = new Handler() {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
//在工作線程中處理所要進(jìn)行的操作
switch (msg.what) {
case MSG_1:
//TODO 處理相關(guān)問題
Log.i("handler", "處理消息MSG_1,當(dāng)前線程名稱:" + Thread.currentThread().getName());
break;
case MSG_2:
//TODO 處理相關(guān)問題
Log.i("handler", "處理消息MSG_2饺饭,當(dāng)前線程名稱:" + Thread.currentThread().getName());
break;
}
}
};
//啟動(dòng)消息隊(duì)列處理工作
Looper.loop();
}).start();
}
/**
* 發(fā)送消息
*/
private void sendMsg() {
//從主線程中發(fā)送消息
Log.i("handler", "發(fā)送MSG_1渤早,當(dāng)前線程名稱:" + Thread.currentThread().getName());
threadHandler.sendEmptyMessage(MSG_1);
new Thread(new Runnable() {
@Override
public void run() {
//從工作線程中發(fā)送消息
Log.i("handler", "發(fā)送MSG_2,當(dāng)前線程名稱:" + Thread.currentThread().getName());
threadHandler.sendEmptyMessage(MSG_2);
}
}).start();
}
/**
* 開啟延遲任務(wù)
*/
private void postTask() {
//主線程中發(fā)送延時(shí)任務(wù)
threadHandler.postDelayed(() -> {
Log.i("handler", "主線程中的postTask瘫俊,當(dāng)前線程名稱:" + Thread.currentThread().getName());
}, 1000);
new Thread(() -> {
//工作線程中發(fā)送延時(shí)任務(wù)
threadHandler.postDelayed(() -> {
Log.i("handler", "工作線程中的postTask鹊杖,當(dāng)前線程名稱:" + Thread.currentThread().getName());
}, 1000);
}).start();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (threadHandler != null) {
//手動(dòng)停止looper悴灵,否則會(huì)引發(fā)內(nèi)存泄漏
threadHandler.getLooper().quit();
}
}
注意Looper.loop();
是一個(gè)雙層嵌套的死循環(huán),需要手動(dòng)的將Looper關(guān)閉(或者關(guān)閉對應(yīng)的線程)骂蓖,否則很容易引發(fā)內(nèi)存泄漏:
if (threadHandler != null) {
threadHandler.getLooper().quit();
}
打印日志:
2021-01-07 12:27:28.903 8206-8373/com.example.behaviorapplication I/handler: 創(chuàng)建threadHandler积瞒,當(dāng)前線程名稱:Thread-6
2021-01-07 12:27:29.904 8206-8206/com.example.behaviorapplication I/handler: 發(fā)送MSG_1,當(dāng)前線程名稱:main
2021-01-07 12:27:29.906 8206-8373/com.example.behaviorapplication I/handler: 處理消息MSG_1登下,當(dāng)前線程名稱:Thread-6
2021-01-07 12:27:29.907 8206-8379/com.example.behaviorapplication I/handler: 發(fā)送MSG_2茫孔,當(dāng)前線程名稱:Thread-8
2021-01-07 12:27:29.907 8206-8373/com.example.behaviorapplication I/handler: 處理消息MSG_2,當(dāng)前線程名稱:Thread-6
2021-01-07 12:27:30.909 8206-8373/com.example.behaviorapplication I/handler: 主線程中的postTask被芳,當(dāng)前線程名稱:Thread-6
2021-01-07 12:27:30.909 8206-8373/com.example.behaviorapplication I/handler: 工作線程中的postTask缰贝,當(dāng)前線程名稱:Thread-6
在工作線程中創(chuàng)建的handler,不管從哪個(gè)線程中發(fā)送的消息或任務(wù)畔濒,所要處理的操作都是在創(chuàng)建handler的線程中剩晴。
我們在主線程中創(chuàng)建Handler時(shí),沒有處理Looper相關(guān)的代碼侵状,是因?yàn)樵赼pp啟動(dòng)主線程創(chuàng)建的過程中已經(jīng)處理過了赞弥,可以在ActivityThread的public static void main(String[] args)
中查看相關(guān)代碼。