Android中有关Handler的使用(三)

Android中有关Handler的使用(三)

d、自己创建新的线程,然后在新线程中创建Looper,主线程调用子线程中的发消息方法,将消息发给子线程的消息队列。

package com.dxyh.test; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; public class MainActivity extends Activity { private final static String TAG = "HandlerTest"; private final static int TASK_BEGIN = 1; private final static int TASK_1 = 2; private final static int TASK_2 = 3; private final static int TASK_END = 4; private Handler workHandler = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.i(TAG, "[M_TID:" + Thread.currentThread().getId() + "]" + "This is in main thread."); LooperThread testThread = new LooperThread(); testThread.start(); // 注意,这里需要等待一下,防止出现空指针异常 while (null == workHandler) { } testThread.sendMessageTodoYourWork(); } class LooperThread extends Thread { @Override public void run() { Looper.prepare(); workHandler = new Handler() { // 现在在每个case之后,你可以做任何耗时的操作了 @Override public void handleMessage(Message msg) { switch (msg.what) { case TASK_BEGIN: Log.i(TAG, "[H_TID:" + Thread.currentThread().getId() + "] Get TASK_BEGIN"); break; case TASK_1: Log.i(TAG, "[H_TID:" + Thread.currentThread().getId() + "] Get TASK_1"); break; case TASK_2: Log.i(TAG, "[H_TID:" + Thread.currentThread().getId() + "] Get TASK_2"); break; case TASK_END: Log.i(TAG, "[H_TID:" + Thread.currentThread().getId() + "] Get TASK_END"); Looper.myLooper().quit(); finish(); break; } super.handleMessage(msg); } }; Looper.loop(); } public void sendMessageTodoYourWork() { Log.i(TAG, "[S_ID:" + Thread.currentThread().getId() + "]" + "Send TASK_START to handler."); // 启动任务(消息只有标识,立即投递) workHandler.sendEmptyMessage(TASK_BEGIN); Log.i(TAG, "[S_ID:" + Thread.currentThread().getId() + "]" + "Send TASK_1 to handler."); // 开始任务1(在workHandler的消息队列中获取一个Message对象,避免重复构造) Message msg1 = workHandler.obtainMessage(TASK_1); msg1.obj = "This is task1"; workHandler.sendMessage(msg1); Log.i(TAG, "[S_ID:" + Thread.currentThread().getId() + "]" + "Send TASK_2 to handler."); // 开启任务2(和上面类似) Message msg2 = Message.obtain(); msg2.arg1 = 10; msg2.arg2 = 20; msg2.what = TASK_2; workHandler.sendMessage(msg2); Log.i(TAG, "[S_ID:" + Thread.currentThread().getId() + "]" + "Send TASK_END to handler."); // 结束任务(空消息体,延时2s投递) workHandler.sendEmptyMessageDelayed(TASK_END, 2000); } } }

运行结果:

Android中有关Handler的使用(三)

e、主/子线程均有一个消息队列,然后相互传递消息(这种方式是最灵活的,双向传递,也不复杂)

package com.dxyh.test; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.util.Log; public class MainActivity extends Activity { private final static String TAG = "HandlerTest"; private final static int TASK_BEGIN = 1; private final static int TASK_1 = 2; private final static int TASK_2 = 3; private final static int TASK_END = 4; private final static int TASK_BEGIN_OVER = 11; private final static int TASK_1_OVER = 12; private final static int TASK_2_OVER = 13; private final static int TASK_END_OVER = 14; private Handler workHandler = null; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.i(TAG, "[M_TID:" + Thread.currentThread().getId() + "]" + "This is in main thread."); LooperThread testThread = new LooperThread(); testThread.start(); // 注意,这里需要等待一下,防止出现空指针异常 while (null == workHandler) { } testThread.sendMessageTodoYourWork(); } Handler mainHandler = new Handler () { // 在每个case之后,不能做耗时的操作 @Override public void handleMessage(Message msg) { switch (msg.what) { case TASK_BEGIN_OVER: Log.i(TAG, "[MH_TID:" + Thread.currentThread().getId() + "] TASK_BEGIN_OVER"); break; case TASK_1_OVER: Log.i(TAG, "[MH_TID:" + Thread.currentThread().getId() + "] TASK_1_OVER"); break; case TASK_2_OVER: Log.i(TAG, "[MH_TID:" + Thread.currentThread().getId() + "] TASK_2_OVER"); break; case TASK_END_OVER: Log.i(TAG, "[MH_TID:" + Thread.currentThread().getId() + "] TASK_END_OVER"); finish(); break; } super.handleMessage(msg); } }; class LooperThread extends Thread { @Override public void run() { Looper.prepare(); workHandler = new Handler() { // 现在在每个case之后,你可以做任何耗时的操作了 @Override public void handleMessage(Message msg) { switch (msg.what) { case TASK_BEGIN: Log.i(TAG, "[ZH_TID:" + Thread.currentThread().getId() + "] Get TASK_BEGIN"); // 做完之后报告信息给主线程 mainHandler.sendEmptyMessage(TASK_BEGIN_OVER); break; case TASK_1: Log.i(TAG, "[ZH_TID:" + Thread.currentThread().getId() + "] Get TASK_1"); // 做完之后报告信息给主线程 mainHandler.sendEmptyMessage(TASK_1_OVER); break; case TASK_2: Log.i(TAG, "[ZH_TID:" + Thread.currentThread().getId() + "] Get TASK_2"); // 做完之后报告信息给主线程 mainHandler.sendEmptyMessage(TASK_2_OVER); break; case TASK_END: Log.i(TAG, "[ZH_TID:" + Thread.currentThread().getId() + "] Get TASK_END"); Looper.myLooper().quit(); // 做完之后报告信息给主线程 mainHandler.sendEmptyMessage(TASK_END_OVER); Looper.myLooper().quit(); break; } super.handleMessage(msg); } }; Looper.loop(); } public void sendMessageTodoYourWork() { Log.i(TAG, "[ZS_ID:" + Thread.currentThread().getId() + "]" + "Send TASK_START to handler."); // 启动任务(消息只有标识,立即投递) workHandler.sendEmptyMessage(TASK_BEGIN); Log.i(TAG, "[ZS_ID:" + Thread.currentThread().getId() + "]" + "Send TASK_1 to handler."); // 开始任务1(在workHandler的消息队列中获取一个Message对象,避免重复构造) Message msg1 = workHandler.obtainMessage(TASK_1); msg1.obj = "This is task1"; workHandler.sendMessage(msg1); Log.i(TAG, "[ZS_ID:" + Thread.currentThread().getId() + "]" + "Send TASK_2 to handler."); // 开启任务2(和上面类似) Message msg2 = Message.obtain(); msg2.arg1 = 10; msg2.arg2 = 20; msg2.what = TASK_2; workHandler.sendMessage(msg2); Log.i(TAG, "[ZS_ID:" + Thread.currentThread().getId() + "]" + "Send TASK_END to handler."); // 结束任务(空消息体,延时2s投递) workHandler.sendEmptyMessageDelayed(TASK_END, 2000); } } }

运行结果:

Android中有关Handler的使用(三)

小结:HandlerAndroid中是很常用的,或是用来更新UI,或是派发任务给子线程去执行,也可以用来产生超时效果,比如用sendMessageDelayed(TASK_TIMEOUT, OUT_TIME)方法。