线程的基础使用(线程之间消息的传递)

        当子线程要发送 Message 给主线程时,首先要为此子线程创建一个Handler 类对象,由Handler调用相应的方法,将需要发送的Message发送到MessageQueue(消息队列)中/当Looper 发现MessageQueu中有未处理的消息时,就会将此消息广播出去,当主线程的 Handler 接收到此 Message 时,就会调用相应的方法来处理这条信息,完成主界面的更新。

效果:

代码:

package com.example.myapplication;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class ThreadActivity extends AppCompatActivity implements View.OnClickListener {

    private TextView tv_show;
    private Button btn_get_message;
    private Handler mainHandler,subHandler;//定义Handler对象
    private static final int ToMain = 1;
    private static final int ToSub  = 2;


    @SuppressLint("HandlerLeak")//注意这段的位置
    class subThread implements Runnable {//创建子线程类
        @Override
        public void run() {
            Looper.prepare();//初始化Looper
            subHandler = new Handler(){//定义子线程的Handler对象
                @Override
                public void handleMessage(Message msg) {//覆写handleMessage
                    switch (msg.what){
                        case ToSub://主线程发送给子线程消息
                            System.out.println("Main Child Message :"+msg.obj);//打印消息
                            Message message = mainHandler.obtainMessage();//创建消息
                            message.obj = "This is a message from Sub";
                            message.what = ToMain;//设置主线程操作的状态码
                            mainHandler.handleMessage(message);//发送
                            break;
                    }
                }
            };
        Looper.loop();//启动该线程的消息队列
        }
    }
    @SuppressLint("HandlerLeak")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_thread);

        tv_show = findViewById(R.id.tv_show);
        btn_get_message = findViewById(R.id.btn_get_message);

        mainHandler = new Handler(){//定义主线程的Handler对象
            @Override
            public void handleMessage(Message msg) {//消息处理
                switch (msg.what){
                    case ToMain:
                        tv_show.setText("主线程接受的数据:"+msg.obj.toString());
                        break;
                }}};
        new Thread( new subThread()).start();//启动子线程
        btn_get_message.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        if(subHandler!=null){
            //判断是否已经实例化子线程Handler
            Message childMsg = subHandler.obtainMessage();
            childMsg.obj ="This is a Message from Main";
            childMsg.what = ToSub;
            subHandler.sendMessage(childMsg);//向子线程发送消息
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        subHandler.getLooper().quit(); //结束队列
    }
}

需要注意的地方:

        创建两个Handler对象,一个是主线程,一个是子线程。通过类subThread实现接口Runnale,并覆写其中的run()方法。run()方法在启动子线程时调用,也就是start()的使用会调用回调方法run()。如下面的代码:

new Thread( new subThread()).start(); new了一个Thread对象,并没给名字。参数里面同样new了一个对象,该类实现了接口Runnable,从而在调用start()方法的时候实现接口回调。

        当进到页面后,先定义主线程的Handler对象,覆写里面的handleMessage()方法来接受子线程发送的消息并进行相应的处理。并通过如下方式启动子线程:

                                                new Thread( new subThread()).start();

        当点击按钮后,会向子线程发送消息。子线程会通过覆写后的handleMessage()方法来接受和处理主线程发送的消息。在此时还会向主线程发送消息,主线程也会通过覆写后的handleMessage()方法来接受和处理子线程发送的消息。

        当然,这是我自己的理解,书上是这样的:

         当子线程要发送 Message 给主线程时,首先要为此子线程创建一个Handler 类对象,由Handler调用相应的方法,将需要发送的Message发送到MessageQueue(消息队列)中/当Looper 发现MessageQueu中有未处理的消息时,就会将此消息广播出去,当主线程的 Handler 接收到此 Message 时,就会调用相应的方法来处理这条信息,完成主界面的更新。

        同时:子线程不能更新主线程的组件数据,否则会报错!!!

        注意Message对象的获取方式:

Message message = mainHandler.obtainMessage();//创建消息

mainHandler可根据相应的Handler对象更改对应名字,尽量不要用new.

       
  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
线程之间消息传递是指在多线程编程中,不同线程之间通过发送和接收消息来交换信息的一种方式。消息传递可以用于线程之间的同步和通信。 实现线程之间消息传递有多种方式。一种常见的方式是通过共享内存的方式实现,即创建一个全局变量或者共享队列,不同线程可以通过读写该变量或队列来传递消息。通过锁或其他同步机制保证多个线程的操作不会相互冲突。 另一种方式是使用线程的阻塞队列。每个线程都有自己的阻塞队列,当需要发送消息时,线程消息放入其他线程的队列中。接收线程则通过阻塞方式等待队列中有消息时再进行处理。这种方式可以避免线程之间的竞争和冲突,并且可以实现异步消息传递消息传递的优点是可以增加线程之间的解耦性,提高系统的可维护性和可扩展性。同时,通过消息传递可以实现线程之间的同步和互斥操作,保证线程之间的安全性。 然而,消息传递也有一些缺点。消息传递通常会引入一定的开销,包括消息的创建和销毁、消息在不同线程之间传递和处理等。同时,消息传递的方式对线程的调度和管理也提出了一定的要求,需要合理地处理线程之间的依赖和顺序。 总结来说,线程之间消息传递是一种常见的多线程编程方式,通过发送和接收消息来实现线程之间的同步和通信。消息传递可以使用共享内存或者阻塞队列等方式实现,它的优点是增加了线程之间的解耦性和安全性,但也存在一定的开销和调度要求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值