在这种情况下,我们会使用 Handler(在 UI 线程创建该对象) 接收子线程的消息更新 UI.
可以看出,这是子线程通知主线程,而主线程没有直接通知子线程,那麽我们如何做到这一点?这样有什么好处?
好处,很明显。主线程中如果有些耗时的操作,我们可以让子线程去做,这时,主线程就可以通知子线程了!
实现这种操作的方式有很多,今天主要想说说 HandlerThread 与 Handler 的配合使用方法。
在主线程中,可以创建 HandlerThread 对象:
- HandlerThread mHandlerThread = new HandlerThread("sub_thread");
- mHandlerThread.start();
这样,就开启了一个子线程,该线程的名字就是 sub_thread.
然后,我们实现一个继承自 Handler 的 MyHandler 类:
- class MyHandler extends Handler {
- public MyHandler() {
- super();
- }
- public MyHandler(Looper looper) {
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {
- // super.handleMessage(msg);
- if(msg.what == MSG_WHAT) {
- Bundle bundle = msg.getData();
- String info = bundle.getString("main");
- Log.d("mark", "我接受任务:" + info);
- }
- }
- }
最后,使用 Message 来传递消息,MyHandler 会根据情况处理 Message.
完整代码:
- package mark.zhang;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.HandlerThread;
- import android.os.Looper;
- import android.os.Message;
- import android.util.Log;
- public class HandlerThreadActivity extends Activity {
- private static final int MSG_WHAT = 1;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- // 创建对象,并启动该线程
- HandlerThread mHandlerThread = new HandlerThread("sub_thread");
- mHandlerThread.start();
- // 获取 Looper 对象
- MyHandler mHandler = new MyHandler(mHandlerThread.getLooper());
- // 创建 Bundle 对象,传递数据
- Bundle bundle = new Bundle();
- bundle.putString("main", "我这边事情太多,麻烦你帮忙处理一下!");
- // 发送消息
- Message msg = new Message();
- msg.what = MSG_WHAT;
- msg.setData(bundle);
- msg.setTarget(mHandler);
- msg.sendToTarget();
- Log.d("mark", "UI----" + "threadName: " + Thread.currentThread().getName() + ",threadId: " + Thread.currentThread().getId());
- }
- /**
- * 该Handler调用 handleMessage方法运行在子线程
- *
- * @author mark
- */
- class MyHandler extends Handler {
- public MyHandler() {
- super();
- }
- /* 这个构造方法必须有 */
- public MyHandler(Looper looper) {
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == MSG_WHAT) {
- Bundle bundle = msg.getData();
- // 接收消息
- String info = bundle.getString("main");
- Log.d("mark", "handleMessage---" + "threadName: " + Thread.currentThread().getName() + ",threadId: " + Thread.currentThread().getId());
- Log.d("mark", "我接受任务:" + info);
- }
- }
- }
- }
这里,我们思考一个问题,代码:
- // 获取 Looper 对象
- MyHandler mHandler = new MyHandler(mHandlerThread.getLooper());
获取 Looper 对象,使用的是 HandlerThread 对象的 getLooper 对象。为什么不直接这样:
- // 获取 Looper 对象
- MyHandler mHandler = new MyHandler(getMainLooper());
如果这样做的话,打印信息如下:
- D/mark (21852): UI----threadName: main,threadId: 1
- D/mark (21852): handleMessage---threadName: main,threadId: 1
- D/mark (21852): 我接受任务:我这边事情太多,麻烦你帮忙处理一下!
可见,此时的 handleMessage 是在主线程中运行的。每个主线程默认有一个 Looper,也就是说在主线程中,下面代码是等效的:
- MyHandler mHandler = new MyHandler(getMainLooper());
- MyHandler mHandler = new MyHandler();
但是子线程需要手动获取如:
- MyHandler mHandler = new MyHandler(mHandlerThread.getLooper());
实现主线程、子线程双向通信可以在各自的线程中分别是用 Handler 来传递信息和处理消息。
在这种情况下,我们会使用 Handler(在 UI 线程创建该对象) 接收子线程的消息更新 UI.
可以看出,这是子线程通知主线程,而主线程没有直接通知子线程,那麽我们如何做到这一点?这样有什么好处?
好处,很明显。主线程中如果有些耗时的操作,我们可以让子线程去做,这时,主线程就可以通知子线程了!
实现这种操作的方式有很多,今天主要想说说 HandlerThread 与 Handler 的配合使用方法。
在主线程中,可以创建 HandlerThread 对象:
- HandlerThread mHandlerThread = new HandlerThread("sub_thread");
- mHandlerThread.start();
这样,就开启了一个子线程,该线程的名字就是 sub_thread.
然后,我们实现一个继承自 Handler 的 MyHandler 类:
- class MyHandler extends Handler {
- public MyHandler() {
- super();
- }
- public MyHandler(Looper looper) {
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {
- // super.handleMessage(msg);
- if(msg.what == MSG_WHAT) {
- Bundle bundle = msg.getData();
- String info = bundle.getString("main");
- Log.d("mark", "我接受任务:" + info);
- }
- }
- }
最后,使用 Message 来传递消息,MyHandler 会根据情况处理 Message.
完整代码:
- package mark.zhang;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.HandlerThread;
- import android.os.Looper;
- import android.os.Message;
- import android.util.Log;
- public class HandlerThreadActivity extends Activity {
- private static final int MSG_WHAT = 1;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- // 创建对象,并启动该线程
- HandlerThread mHandlerThread = new HandlerThread("sub_thread");
- mHandlerThread.start();
- // 获取 Looper 对象
- MyHandler mHandler = new MyHandler(mHandlerThread.getLooper());
- // 创建 Bundle 对象,传递数据
- Bundle bundle = new Bundle();
- bundle.putString("main", "我这边事情太多,麻烦你帮忙处理一下!");
- // 发送消息
- Message msg = new Message();
- msg.what = MSG_WHAT;
- msg.setData(bundle);
- msg.setTarget(mHandler);
- msg.sendToTarget();
- Log.d("mark", "UI----" + "threadName: " + Thread.currentThread().getName() + ",threadId: " + Thread.currentThread().getId());
- }
- /**
- * 该Handler调用 handleMessage方法运行在子线程
- *
- * @author mark
- */
- class MyHandler extends Handler {
- public MyHandler() {
- super();
- }
- /* 这个构造方法必须有 */
- public MyHandler(Looper looper) {
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == MSG_WHAT) {
- Bundle bundle = msg.getData();
- // 接收消息
- String info = bundle.getString("main");
- Log.d("mark", "handleMessage---" + "threadName: " + Thread.currentThread().getName() + ",threadId: " + Thread.currentThread().getId());
- Log.d("mark", "我接受任务:" + info);
- }
- }
- }
- }
这里,我们思考一个问题,代码:
- // 获取 Looper 对象
- MyHandler mHandler = new MyHandler(mHandlerThread.getLooper());
获取 Looper 对象,使用的是 HandlerThread 对象的 getLooper 对象。为什么不直接这样:
- // 获取 Looper 对象
- MyHandler mHandler = new MyHandler(getMainLooper());
如果这样做的话,打印信息如下:
- D/mark (21852): UI----threadName: main,threadId: 1
- D/mark (21852): handleMessage---threadName: main,threadId: 1
- D/mark (21852): 我接受任务:我这边事情太多,麻烦你帮忙处理一下!
可见,此时的 handleMessage 是在主线程中运行的。每个主线程默认有一个 Looper,也就是说在主线程中,下面代码是等效的:
- MyHandler mHandler = new MyHandler(getMainLooper());
- MyHandler mHandler = new MyHandler();
但是子线程需要手动获取如:
- MyHandler mHandler = new MyHandler(mHandlerThread.getLooper());
实现主线程、子线程双向通信可以在各自的线程中分别是用 Handler 来传递信息和处理消息。
在这种情况下,我们会使用 Handler(在 UI 线程创建该对象) 接收子线程的消息更新 UI.
可以看出,这是子线程通知主线程,而主线程没有直接通知子线程,那麽我们如何做到这一点?这样有什么好处?
好处,很明显。主线程中如果有些耗时的操作,我们可以让子线程去做,这时,主线程就可以通知子线程了!
实现这种操作的方式有很多,今天主要想说说 HandlerThread 与 Handler 的配合使用方法。
在主线程中,可以创建 HandlerThread 对象:
- HandlerThread mHandlerThread = new HandlerThread("sub_thread");
- mHandlerThread.start();
这样,就开启了一个子线程,该线程的名字就是 sub_thread.
然后,我们实现一个继承自 Handler 的 MyHandler 类:
- class MyHandler extends Handler {
- public MyHandler() {
- super();
- }
- public MyHandler(Looper looper) {
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {
- // super.handleMessage(msg);
- if(msg.what == MSG_WHAT) {
- Bundle bundle = msg.getData();
- String info = bundle.getString("main");
- Log.d("mark", "我接受任务:" + info);
- }
- }
- }
最后,使用 Message 来传递消息,MyHandler 会根据情况处理 Message.
完整代码:
- package mark.zhang;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.HandlerThread;
- import android.os.Looper;
- import android.os.Message;
- import android.util.Log;
- public class HandlerThreadActivity extends Activity {
- private static final int MSG_WHAT = 1;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- // 创建对象,并启动该线程
- HandlerThread mHandlerThread = new HandlerThread("sub_thread");
- mHandlerThread.start();
- // 获取 Looper 对象
- MyHandler mHandler = new MyHandler(mHandlerThread.getLooper());
- // 创建 Bundle 对象,传递数据
- Bundle bundle = new Bundle();
- bundle.putString("main", "我这边事情太多,麻烦你帮忙处理一下!");
- // 发送消息
- Message msg = new Message();
- msg.what = MSG_WHAT;
- msg.setData(bundle);
- msg.setTarget(mHandler);
- msg.sendToTarget();
- Log.d("mark", "UI----" + "threadName: " + Thread.currentThread().getName() + ",threadId: " + Thread.currentThread().getId());
- }
- /**
- * 该Handler调用 handleMessage方法运行在子线程
- *
- * @author mark
- */
- class MyHandler extends Handler {
- public MyHandler() {
- super();
- }
- /* 这个构造方法必须有 */
- public MyHandler(Looper looper) {
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == MSG_WHAT) {
- Bundle bundle = msg.getData();
- // 接收消息
- String info = bundle.getString("main");
- Log.d("mark", "handleMessage---" + "threadName: " + Thread.currentThread().getName() + ",threadId: " + Thread.currentThread().getId());
- Log.d("mark", "我接受任务:" + info);
- }
- }
- }
- }
这里,我们思考一个问题,代码:
- // 获取 Looper 对象
- MyHandler mHandler = new MyHandler(mHandlerThread.getLooper());
获取 Looper 对象,使用的是 HandlerThread 对象的 getLooper 对象。为什么不直接这样:
- // 获取 Looper 对象
- MyHandler mHandler = new MyHandler(getMainLooper());
如果这样做的话,打印信息如下:
- D/mark (21852): UI----threadName: main,threadId: 1
- D/mark (21852): handleMessage---threadName: main,threadId: 1
- D/mark (21852): 我接受任务:我这边事情太多,麻烦你帮忙处理一下!
可见,此时的 handleMessage 是在主线程中运行的。每个主线程默认有一个 Looper,也就是说在主线程中,下面代码是等效的:
- MyHandler mHandler = new MyHandler(getMainLooper());
- MyHandler mHandler = new MyHandler();
但是子线程需要手动获取如:
- MyHandler mHandler = new MyHandler(mHandlerThread.getLooper());
实现主线程、子线程双向通信可以在各自的线程中分别是用 Handler 来传递信息和处理消息。