Handler工作原理和处理线程间通讯

消息处理的五大组成部分:

  • Message
  • Handler
  • Message Queue
  • Looper
  • ThreadLocal

1、Message数据模型,用于线程之间传递消息,

常用四个字段:

target:消息回调的作用域类,通常是一个handler,为了内部区分多个handler问题;

what:区分不同消息得标识符;

obj:是一个对象类型,可以携带自定义的类;

arg:int类型携带参数;

2、handler主要用于发送和接收消息

sendMessage();主要用于发送和处理消息;

handleMessage();发出的消息经过一系列出来后,最终会传递到handler的handlemessage方法中;

3、MessageQueue消息队列

主要存放所有handler发送过来的消息,这些消息存放在消息队列中,等待被处理,每一个线程只有一个messageQueue队列

4、Looper

每个线程通过Handler发送的消息都保存在messageQueue中,Looper通过调用loop()方法,就会进入到一个无限循坏中,然后每当发现MessageQueue中存在一条消息,就会将它取出,并传递到handler的handleMessage()方法中,每个贤臣中只会有一个Looper对象;

一、Handler常规使用:更新主线程UI

private MyHandler myHandler = new MyHandler(this);
    private class MyHandler extends Handler {

        private WeakReference<Activity> mWeakReference;

        public MyHandler(Activity activity) {
            super();
            mWeakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            Activity activity = mWeakReference.get();
            if (activity == null) return;
            switch (msg.what) {
                case 1:
                    /**
                     * 非静态内部类会隐式地持有外部类的引用(MainActivity中TextView),这回导致外部类对象无法被系统的GC回收;
                     * 解决:
                     * 1、静态内部类持有外部类引用
                     * 2、弱引用的方式来持有外部类引用
                     */
                    System.out.println("----->" + msg);
                    textView.setText(msg.toString());
                    break;
            }
        }
    }
...
  private void sendThread() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Message message = Message.obtain();
                message.what = 1;
                message.obj = "线程发送消息----";
                //长时间持有Handler引用,handleMessage
                myHandler.sendMessage(message);
                //mHandler.sendMessageDelayed(message, 10000);
            }
        }).start();
    }

二、Handler跨线程通信

1、接受消息的线程:创建Looper,循环取出消息队列MessageQueue里面的消息,并分发到创建该消息得处理者Handler;

2、发送消息线程:创建Message消息,并使用接收线程中Handler发送消息;

public class MainActivity extends AppCompatActivity {

    private TextView textView;

    private Handler thread2Handler;

    private Handler mainHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            textView.setText(msg.toString());
            return false;
        }
    });

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.textview);

        findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                thread1();
            }
        });

        findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();//准备
                thread2Handler = new Handler(new Handler.Callback() {
                    @Override
                    public boolean handleMessage(@NonNull Message msg) {
                        if (msg != null) {
                            System.out.println("线程2接收到消息:" + msg);
                            Message reply = Message.obtain();
                            reply.obj = msg.obj;
                            mainHandler.sendMessage(reply);
                        }
                        return false;
                    }
                });
                Looper.loop();//轮询
            }
        }).start();
    }

    private void thread1() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Message message = Message.obtain();
                message.obj = "我是线程1";
                if (thread2Handler != null) {
                    thread2Handler.sendMessage(message);
                } else {
                    System.err.println("thread2Handler未准备完成");
                }
            }
        }).start();
    }
}

参考:

https://www.jianshu.com/p/ba46bad5af67

https://www.cnblogs.com/liushilin/p/8667917.html?foxhandler=RssReadRenderProcessHandler#commentform

https://blog.csdn.net/KevinsCSDN/article/details/81428566

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值