整合代码
//总结:handler 用于 Android 线程之间的通信
public class MainActivity extends AppCompatActivity {
final static String TAG1 = "Main";
final static String TAG2 = "Sub";
Handler mHandler, subHandler;
HandlerThread handlerThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.d(TAG1, msg.what + " -- " + Thread.currentThread().getName());
}
};
handlerThread = new HandlerThread("test_handler");
handlerThread.start();
//子线程从 主线程或其他子线程 收消息,再发回到主线程
subHandler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
Log.d(TAG2, msg.what + " -- " + Thread.currentThread().getName());
//子线程发送到主线程
mHandler.sendEmptyMessage(msg.what);
//subHandler.sendEmptyMessageDelayed(4, 1000);//自己调用自己可以达到计时器的效果
}
};
//主线程发送消息到子线程
subHandler.sendEmptyMessage(2);
//子线程发送消息到子线程
new Thread(new Runnable() {
@Override
public void run() {
subHandler.sendEmptyMessage(3);
//子线程中切换到UI线程
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Log.d("NewThread", Thread.currentThread().getName());
}
});
//子线程中切换到UI线程 2
//runOnUiThread 当前线程在UI线程则直接run,不是则用handler发布到事件队列的UI线程
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d("runOnUiThread", Thread.currentThread().getName());
}
});
}
}).start();
}
@Override
protected void onDestroy() {
super.onDestroy();
handlerThread.quit();
}
}
运行结果
D/Sub: 2 -- test_handler //主线程发送信息到子线程
D/Sub: 3 -- test_handler //子线程发送信息到子线程
D/Main: 2 -- main
D/Main: 3 -- main //子线程收到信息发送到主线程
D/NewThread: main //子线程切换到主线程
D/runOnUiThread: main //子线程切换到主线程
runOnUiThread 源码解析
public final void runOnUiThread(Runnable action) {
if (Thread.currentThread() != mUiThread) { //当前线程不是UI线程
mHandler.post(action); //利用Activity中的Handler发布到UI线程的事件队列中
} else {
action.run(); //当前线程为UI线程,则直接执行
}
}