說來慚愧,工作三年了,都沒了徹底解Android的幾個重要的機制,只是會用,最近找工作被問的懵逼,所以我決定徹底瞭解這些機制,今天說的是Handler機制。
Handler機制每個人都能說出個大概,但是具體怎麼實現的,估計很多人都說不出來,看源碼又很枯燥,我就對着幾個博客,嘗試着自己實現自己的Handler機制,而且我成功了,貼出自己的小Demo,希望能幫助到各位同行。
package com.example.handlerdemo;
import android.content.Context;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class MyHandlerActivity extends AppCompatActivity {
private static String TAG = "MyHandlerActivity";
public MyHanler mHander;
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_my_handler);
mHander = new MyHanler() {
@Override
public void sendMessage(MyMessage myMessage) {
// 模擬將Msg放人MessageQueue,這裏只有一條消息,所以只有簡單的賦值操作
Log.e(TAG, "handlerMessage");
this.msg = myMessage;
}
@Override
public void handleMessage(MyMessage myMessage) {
Log.e(TAG, "handleMessage");
Toast.makeText(mContext, "我的自定義Handler", Toast.LENGTH_SHORT).show();
}
};
MyThread childThread = new MyThread();
childThread.start();
}
@Override
protected void onResume() {
super.onResume();
// 在主線程中啓動消息循環,拿到不爲空的消息對象後調用handleMessage,
// 這樣就實現了子線程發送的消息,並引發主線程中的方法調用
mHander.loop();
}
/*
模擬Handler,簡化沒有Loop和MQ
只能接受一條消息
我一開始嘗試直接在MyThread中調用MyHanler的handleMessage方法,但這樣會報錯
因爲直接調用MyHanler的方法,這個方法其實還是在子線程中運行,所以彈Toast的時候會報異常
而MyHanler發送一個消息對象,在MyHanler中啓動一個死循環拿消息再調用handleMessage就是在自己的線程中執行
這就是爲什麼Android要用一個複雜的Handler機制來實現線程間通信
*/
abstract class MyHanler {
MyMessage msg;
public MyHanler() {
}
public void loop() {
// 模擬Loop的消息循環
for (; ; ) {
Log.w(TAG, "looping");
if (null != msg) {
Log.e(TAG, "getMessage");
handleMessage(msg);
return;
}
}
}
abstract void sendMessage(MyMessage myMessage);
abstract void handleMessage(MyMessage myMessage);
}
class MyThread extends Thread {
@Override
public void run() {
// mHander.handlerMessage(0);
MyMessage msg = new MyMessage(0); // 實例化消息對象
mHander.sendMessage(msg);
}
}
}
相信Android的Handler機制是在這個原理上完善的。如有不對,請指正