主线程和子线程之间传递消息

本文介绍了一个Android应用中实现子线程与主线程通信的例子。通过自定义的MyThread类,使用Handler机制在子线程中进行计算,并将结果发送回主线程更新UI。文章详细展示了如何在子线程中接收数据,执行斐波那契数列计算,并通过Message对象将结果传回主线程进行处理。

在这里插入图片描述



<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="设置一个整数"/>

    <EditText
        android:id="@+id/et_num"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="计算结果为"/>
    <TextView
        android:id="@+id/tv_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/btn_start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="开始计算"/>
</LinearLayout>


public class MainActivity extends AppCompatActivity {

    private static final int NUMBER = 1;
    private static final int RESULT = 0;
    private MyThread myThread;
    private TextView tvResult;
    private EditText etNum;
    //主线程Handler
    private Handler mainHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //处理Message,运行在主线程,可以修改界面元素
            switch (msg.what) {
                case RESULT:
                    long res = (long) msg.obj;
                    tvResult.setText(res + "");
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvResult = findViewById(R.id.tv_result);
        etNum = findViewById(R.id.et_num);
        //创建子线程
        myThread = new MyThread();
        myThread.start();
        Button button = findViewById(R.id.btn_start);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String str = etNum.getText().toString();
                //向子线程发送数据
                Message message = new Message();
                message.what = NUMBER;
                message.obj = Integer.parseInt(str);
                workHandler.sendMessage(message);
            }
        });
    }

    //子线程的Handler
    private Handler workHandler;

    private class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            //子线程中使用Handler要手动开启Looper
            Looper.prepare();
            workHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    //处理来自主线程的数据
                    switch (msg.what){
                        case NUMBER:
                            long res = fib((int)msg.obj);
                            //发送Message
                            Message message = new Message();
                            //添加数据
                            message.obj = res;
                            //添加标识
                            message.what = RESULT;
                            mainHandler.sendMessage(message);
                            break;
                    }

                }
            };
            Looper.loop();

            //不能直接在子线程中修改UI
//            tvResult.setText(res+"");
        }
    }

    private long fib(int n) {
        if (n == 1) {
            return 1;
        } else if (n == 2) {
            return 1;
        } else {
            return fib(n - 1) + fib(n - 2);
        }
    }
}

<think>嗯,用户想了解Android中Handler处理主线程子线程之间消息通信机制及用法。我需要先回忆一下Handler的基本概念相关组件。根据提供的引用内容,Handler涉及Looper、MessageQueue、Message等类,可能还需要提到HandlerThread。 首先,用户的问题可能涉及如何创建Handler实例,以及在主线程子线程中的不同使用方式。主线程默认有Looper,所以可以直接创建Handler,而子线程需要自己准备Looper。比如,子线程中使用Handler时需要先调用Looper.prepare()Looper.loop(),或者使用HandlerThread来简化这个过程。 然后,用户可能关心消息处理流程。比如,子线程消息主线程的Handler,或者主线程消息子线程的Handler。需要解释Message的创建方式,如obtainMessage()post(Runnable),以及如何重写handleMessage方法处理消息。 还要注意线程安全问题,比如子线程不能直接更新UI,必须通过主线程的Handler来处理。引用中的示例代码可能有用,比如使用HandlerThread来创建带有Looper的子线程,这样在子线程间通信更方便。 另外,需要提到不同的通信场景,比如子线程主线程子线程子线程,每种情况下的实现步骤注意事项。比如在子线程中实例化主线程的Handler,或者在子线程中创建自己的Handler并获取其Looper传递给其他线程。 可能还需要说明如何避免内存泄漏,比如使用静态内部类或者弱引用。同时,引用中的内容提到HandlerThread可以避免手动处理Looper的创建等待问题,这一点需要强调,因为它简化了多线程通信的实现。 最后,整理步骤,给出代码示例,并确保符合用户的需求,即机制用法的详细说明。确保回答结构清晰,分点说明,并包含相关问题以供进一步学习。</think>### Android Handler主线程子线程通信机制详解 Android的Handler机制是线程间通信的核心方案,通过**消息队列**实现线程安全的通信。以下是具体实现步骤代码示例: --- #### 一、核心组件作用 1. **Handler**:消息处理器,支持`sendMessage()``post(Runnable)`两种方式[^2][^4] 2. **Message**:携带数据的消息对象,推荐用`obtainMessage()`复用实例 3. **MessageQueue**:消息存储队列,每个线程有独立实例 4. **Looper**:消息循环器,不断从队列取出消息主线程默认启动[^5] --- #### 二、主线程子线程通信实现步骤 **1. 子线程主线程(更新UI)** ```java // 主线程创建Handler Handler mainHandler = new Handler(Looper.getMainLooper()) { @Override public void handleMessage(Message msg) { textView.setText("收到消息:" + msg.obj); // 主线程更新UI } }; // 子线程消息 new Thread(() -> { Message msg = mainHandler.obtainMessage(); msg.obj = "来自子线程的数据"; mainHandler.sendMessage(msg); }).start(); ``` **2. 主线程子线程** ```java // 创建带Looper的子线程 HandlerThread workThread = new HandlerThread("WorkThread"); workThread.start(); // 绑定子线程的Handler Handler workHandler = new Handler(workThread.getLooper()) { @Override public void handleMessage(Message msg) { Log.d("WorkThread", "处理耗时操作:" + msg.obj); } }; // 主线程消息 workHandler.sendMessage(workHandler.obtainMessage(0, "下载任务")); ``` --- #### 三、关键注意点 1. **Looper准备**:子线程使用Handler必须先调用`Looper.prepare()``Looper.loop()`[^5] 2. **线程绑定**:Handler实例与创建时的Looper所在线程绑定 3. **内存泄漏**:建议使用静态内部类+弱引用处理Activity上下文 4. **消息优先级**:`sendMessageAtFrontOfQueue()`可插队处理紧急消息 --- #### 四、HandlerThread优化方案 ```java HandlerThread handlerThread = new HandlerThread("NetworkThread"); handlerThread.start(); Handler networkHandler = new Handler(handlerThread.getLooper()) { @Override public void handleMessage(Message msg) { // 执行网络请求等IO操作 } }; ``` 该方案自动管理Looper生命周期,避免手动处理线程同步问题[^3][^5] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值