`
lvwenwen
  • 浏览: 958693 次
  • 性别: Icon_minigender_1
  • 来自: 魔都
社区版块
存档分类
最新评论

Handler: 主线程如何通知子线程

阅读更多
Handler: 主线程如何通知子线程
分类: Android 2012-01-02 10:48 4772人阅读 评论(18) 收藏 举报
在 android 中,不可以在子线程中更新 UI 的操作,否则会报错或者异常信息。

在这种情况下,我们会使用 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主线程于子线程,子线程与子线程,主线程到子线程消息传递

    Handler消息传递详解,子线程到子线程,主线程到子线程,子线程到主线程 三种消息,Looper,Handler工作机制详解 https://blog.csdn.net/shoneworn/article/details/80447651

    android 主线程给子线程发送消息

    当主线程的`Handler`接收到子线程发送的消息后,会调用`handleMessage(Message msg)`方法进行处理,这里可以更新UI或者执行其他需要在主线程进行的操作。 6. **示例代码**: ```java // 主线程的Handler class ...

    android主线程、子线程及线程间通信方式测试app

    - **Handler**:在主线程中创建一个Handler对象,并关联到Looper,然后子线程可以通过发送Message对象到Handler,由主线程处理。这种方式适用于异步任务的结果返回到UI线程更新界面。 - **Runnable**:可以直接...

    子线程和主线程通过handler 双向通信

    本文将深入探讨如何使用Handler机制实现主线程与子线程,以及HandlerThread之间的双向通信。 首先,理解Android的线程模型至关重要。主线程,也称为UI线程,负责处理所有的用户交互和更新UI。由于Android系统对主线...

    子线程更新主线程数据

    - Handler: 主线程中的Handler对象可以接收并处理由其他线程(通常是子线程)通过Looper和Message发送的消息。Message对象可以携带数据,这样子线程就可以将数据封装在Message中,然后通过Handler发送到主线程。 -...

    Android主线程和子线程区别详解

    3. 如果需要在子线程中更新UI,必须通过Handler、runOnUiThread或使用Android提供的AsyncTask等机制,将任务回调到主线程执行。 在给定的代码示例中,可以看到以下几个关键点: 1. 使用委托(Delegate)来定义多个...

    子线程接收主线程发送的消息

    5. **发送消息**:在主线程中,通过之前创建的主线程Handler使用`sendMessage()`或`post()`方法向子线程的Handler发送Message。 6. **处理消息**:子线程的Handler会在其Looper的消息循环中接收到主线程发送的消息...

    android demo,实现主线程handle,工作子线程threadHandle的处理

    这个概念可能是指在子线程中创建的Handler实例,用于与主线程的Handler进行通信。通常,我们在子线程中创建一个Handler,然后通过Looper.prepare()和Looper.loop()来启动一个消息循环,使子线程也能接收和处理消息...

    Android Handler主线程和一般线程通信的应用分析

    Handler的定义:主要接受子线程发送的数据, 并用此数据配合主线程更新UI.解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进行事件分发, 比如说, 你要是点击一个...

    Looper和Handler实现UI线程和子线程的通信

    1. 在子线程中,创建一个Handler实例,并将其与主线程的Looper关联。这通常通过在子线程中调用Looper.prepare()和Looper.loop()完成。 2. 创建一个Message对象,并设置其what属性来标识消息类型,或者通过Bundle传递...

    安卓UI线程机制 ,在子线程中访问UI

    2. 使用Handler:为了在子线程中更新UI,可以创建一个与主线程关联的Handler实例。在子线程中,创建Message,设置其目标为该Handler,然后调用sendMessage()方法将Message放入主线程的MessageQueue。主线程的Looper...

    Android主线程给多个线程发送消息

    总结来说,Android主线程通过`Handler`和`Looper`机制可以有效地与多个工作线程进行通信。这种模式不仅避免了直接操作UI的潜在风险,还确保了UI更新的同步性,是Android异步编程的重要工具。在实际项目中,还可以...

    利用Handler在线程之间传递数据

    这个demo介绍了通过Handler在线程之间传递消息,demo中一个三个线程,主线程,发送消息的分线程,接收消息的分线程。发送消息的分线程会通知主线程更改标签文字,同时会通知接收消息的分线程更改进度条的进度。

    【Android开发入门】Android线程之Handler

    Android系统主要分为两个线程:主线程(UI线程)和工作线程。主线程负责处理用户界面的绘制和事件响应,而工作线程用于执行耗时操作,避免阻塞UI。由于Android系统的安全限制,直接在工作线程中更新UI是不允许的,这...

    android里如何在子线程中如何更新主线程的控件

    因此,要在子线程中更新主线程的控件,你需要利用Android的消息传递机制,主要是通过`Message`和`Handler`来实现。 首先,理解`Handler`和`Looper`的角色。`Handler`是消息处理器,负责接收和处理来自其他线程的...

    android主线程和子线程之间消息传递详解

    为了在主线程和子线程之间进行有效的通信,Android提供了消息传递机制,主要通过Handler、Looper和Message三个关键组件来实现。 首先,我们来看如何从主线程发送消息到子线程。在给定的代码示例中,创建了一个名为`...

    Android环境下主UI线程与子线程通信机制研究.pdf

    子线程通过Handler、Looper和Message机制来通知主线程进行UI更新。具体来说,子线程会创建一个Message对象,并通过Handler将消息发送到主线程的消息队列中。主线程的Looper会不断地从消息队列中取出消息,并在主线程...

    Handler 消息机制 多线程 应用场景

    通过Handler、Looper和Message三者之间的协同工作,开发者可以在主线程与子线程之间进行安全的数据传递和任务调度。 首先,我们来理解Handler的基本概念。Handler是Android中的一个类,用于发送和处理消息。它的...

    android Handler子线程计算斐波那契数列

    在Android应用开发中,Handler是用于处理主线程与子线程之间通信的重要工具。它允许开发者在后台线程执行耗时操作(如计算斐波那契数列),然后通过Message对象将结果回调到主线程更新UI。在这个场景中,我们讨论的...

    线程,线程池与Handler的用法

    在Android开发中,线程和线程池是处理异步任务的重要工具,而Handler则是用于在主线程和子线程之间通信的关键组件。本篇文章将深入探讨这些概念,以及它们在实际应用中的用法。 首先,让我们理解什么是线程。线程是...

Global site tag (gtag.js) - Google Analytics