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

        当子线程要发送 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、付费专栏及课程。

余额充值