一起Talk Android吧(第一百八十回:Android中的Handler机制九)

本文深入讲解Android中Handler机制的应用,通过实例演示如何在主线程与子线程间发送消息,展示消息处理流程及UI更新技巧。

各位看官们大家好,上一回中咱们说的是Android中Handler机制的例子,这一回咱们继续说该例子。闲话休提,言归正转。让我们一起Talk Android吧!

看官们,由于时间的原因我们在上一回中只演示了布局文件,这一回将演示Activity的代码,下面是具体的代码,请大家参考:

package com.example.talk8.blogapp05_handler;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private TextView mNameMainThread;
    private TextView mIDMainThread;
    private Button mBTStartMsg;
    private Button mBTEndMsg;
    private TextView mNameSubThread;
    private TextView mIDSubThread;
    private Button mBTShowName;
    private Button mBTdShowId;
    //消息类型
    private final int MSG_START = 0;
    private final int MSG_END = 1;
    private final int MSG_SHOW_NAME = 2;
    private final int MSG_SHOW_ID = 3;

    private Thread mSubThread;
    public SubHandler mSubHandler;
    public  Handler  mSubThreadHandler;
    public Looper mSubThreadLooper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //通过TextView控件显示主线程的名字和线程ID
        mNameMainThread = (TextView)findViewById(R.id.id_tv_name_main_thread);
        mIDMainThread = (TextView)findViewById(R.id.id_tv_id_main_thread);
        //通过Button控件向消息队列中来发送消息,这里有两个Button用来发送不同的消息
        mBTStartMsg = (Button) findViewById(R.id.id_bt_start_message);
        mBTEndMsg = (Button) findViewById(R.id.id_bt_end_message);

        //通过TextView控件显示子线程的名字和线程ID
        mNameSubThread = (TextView)findViewById(R.id.id_tv_name_sub_thread);
        mIDSubThread = (TextView)findViewById(R.id.id_tv_id_sub_thread);

        //通过Button控件来修改主线程中的控件内容,使其显示子线程的名字和ID
        mBTShowName = (Button) findViewById(R.id.id_bt_show_name);
        mBTdShowId = (Button) findViewById(R.id.id_bt_show_id);

        //创建自定义的Handler对象
        mSubHandler = new SubHandler();

        //创建子线程,并且在子线程中实现属于子线程自己的Handler机制
        mSubThread = new Thread( () ->{
            //1.初始化消息队列
            Looper.prepare();
            //2.创建子线程自己的Looper
            mSubThreadLooper = Looper.myLooper();
            if(mSubThreadLooper != null) {
                //3.创建子线程自己的Handler类对象,这里是匿名对象
                  mSubThreadHandler = new Handler() {
                    @Override
                    public void handleMessage(Message msg) {
                        //重写Handler方法用来处理消息队列中的消息
                        super.handleMessage(msg);
                        switch (msg.what){
                            case MSG_SHOW_NAME:
                                Toast.makeText(getApplicationContext(),""+msg.obj,Toast.LENGTH_LONG).show();
                                sendMsg(msg.what,""+msg.obj); //send msg to Main thread
                                break;
                            case MSG_SHOW_ID:
                                Toast.makeText(getApplicationContext(),""+msg.obj,Toast.LENGTH_LONG).show();
                                sendMsg(msg.what,""+msg.obj);
                                break;
                             default:
                                break;
                        }
                    }
                };
                //4.启动消息队列
                Looper.loop();
            }else {
                sendMsg(0,"sub looper is null");
            }
            //5.销毁子线程的Looper以及消息队列
            mSubThreadLooper.quit();
        });

        mSubThread.start();

        mNameMainThread.setText("Nmae: "+Looper.myLooper().toString());
        mIDMainThread.setText("ID: "+Thread.currentThread().getId());

        //给主线程中的消息队列中发送消息
        mBTStartMsg.setOnClickListener(v ->sendMsg(MSG_START,"Start"));
        mBTEndMsg.setOnClickListener(v -> sendMsg(MSG_END,"End"));

        mNameSubThread.setText("Name: "+ mSubThread.getName());
        mIDSubThread.setText("ID: "+mSubThread.getId());

        //显示子线程的名字和ID
        mBTShowName.setOnClickListener(v -> showName() );
        mBTdShowId.setOnClickListener(v -> showId());
    }

    //
    public class SubHandler extends Handler {
        //主线程中的消息处理,前两条消息,只是弹出Toast,并且显示消息内容
        //后两条消息是从子线程中发出的,用来显示子线程的名字和ID
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what){
                case MSG_START:
                    showMessage(msg.obj.toString());
                    break;
                case MSG_END:
                    showMessage(msg.obj.toString());
                    break;
                case MSG_SHOW_NAME:
                    mNameSubThread.setText((String)msg.obj);
                    break;
                case MSG_SHOW_ID:
                    mIDSubThread.setText((String)msg.obj);
                    break;
                default:
                    showMessage(msg.obj.toString());
                    break;
            }
        }
    }

    //向主线程的消息队列中发送消息
    public void sendMsg(int type,String content) {
        Message msg = new Message();
        msg.what = type;
        msg.obj =content;
       mSubHandler.sendMessage(msg);
    }

    public void showMessage(String s) {
        String text ="Recived Message,It is: ";

        if(s != null) {
            Toast.makeText(getApplicationContext(), text+s, Toast.LENGTH_LONG).show();
        }else {
            Toast.makeText(getApplicationContext(), text+"empty." , Toast.LENGTH_LONG).show();
        }
    }

    public void showName() {
       Message m = new Message();
       m.what = MSG_SHOW_NAME;
       m.obj= "Name: "+mSubThreadLooper.toString();
       mSubThreadHandler.sendMessage(m);
    }

    public  void showId() {
        Message m = new Message();
        m.what = MSG_SHOW_ID;
        m.obj= "Id: "+mSubThread.getId();
        mSubThreadHandler.sendMessage(m);
    }
}

看官们,我们在代码中主要的地方都添加了注释,并且在部分涉及到流程的地方还添加了数字符号,请大家结合我们在前面章回中介绍的Handler使用步骤来查看代码,相信大家都可以看明白。下面是程序的运行结果,请大家参考。
在这里插入图片描述
结合代码和程序运行结果,我们对此程序做一些说明:
在主线程中我们通过点击按钮来向消息队列中发送消息,主线程的Handler收到消息后弹出Toast并且显示消息内容;大家注意,主线程中的Looper是Activity创建的,我们在前面章回中分析过,为了更好的演示Handler机制,我们使用Thread创建了子线程,并且在子线程创建了Looper以及Handler,子线程中也是通过点击按钮发送消息的,子线程的Handler收到消息后又把消息发送了主线程的消息队列中,主线程的Handler收到消息后在屏幕上显示子线程的名称的ID。这个感觉有点绕呀,为什么不直接在子线程中显示子线程的名称的ID?

各位看官,关于Android中Handler机制的例子咱们就介绍到这里,欲知后面还有什么例子,且听下回分解!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

talk_8

真诚赞赏,手有余香

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值