主线程和子线程通信

默认情况下新增的线程是没有开启消息循环的(主线程除外,会默认创建Looper对象,开启消息循环)

一般情况下都是子线程向主线程发送消息,主线程中已经默认实现了Looper的操作。只需要创建Handler 开启线程发送消息 主线程中接收消息处理就可以了

Looper:消息队列(MessageQueue)的管家(Looper)。一个消息队列只有一个管家,但是Handler(工人)可以有多个。Looper管理者handler向MessageQueue中存储和取出消息之后执行任务。

所以他们的个数:

管家(Looper): 1 个; 
消息队列(MessageQueue):1 个; 
消息(Message):可以多个; 

工人(Handler):可以多个;


而这里研究的是主线程向子线程发送消息,所以要在子线程中创建Handler必须用到Looper。


Looper.prepare()来给线程创建一个消息循环,Looper.loop()让Looper开始工作,从消息队列里取消息,处理消息。 

注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。


  • 主线程和子线程通信:


public class MainActivity2 extends BaseActivity {


    Button buttonMainToChild;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

       
        //onCreate中默认开启线程 LooperThread
        //线程创建是一个耗时的操作 如果放到click中创建的话 紧接着发送消息的话 可能handler还没创建就已经发送消息了
        //click方法中只是发送消息
        final LooperThread looperThread = new LooperThread();
        new Thread(looperThread).start();


        buttonMainToChild = (Button) findViewById(R.id.button_main_to_child);
        buttonMainToChild.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Message msMessage = new Message();
                msMessage.arg1 = 3;
                looperThread.handler.sendMessage(msMessage);
            }
        });

    }

   
    //LooperThread
    class LooperThread implements Runnable {

        public Handler handler;

        @Override
        public void run() {

            Looper.prepare();

            handler = new Handler(){

                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);

                    Log.d(TAG, "handleMessage: LooperThread 消息是:" + msg.arg1);
                    
                }
            };
            Looper.loop();

        }
    }

}


注意:

1、Handler的创建是在子线程中,调用的时候也得注意是子线程中的handler

2、这里默认是在onCreate中开启线程,在onclick中发送消息。线程创建是一个耗时的操作 如果放到click中创建的话 紧接着发送消息的话 可能handler还没创建就已经发送消息了




  • HandlerThread实现主线程和子线程通信:
Button buttonMainToChild2;


    private Handler mHandler;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

     
        buttonMainToChild2 = (Button) findViewById(R.id.button_main_to_child2);
        buttonMainToChild2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //实例化一个特殊的线程HandlerThread,必须给其指定一个名字
                HandlerThread handlerThread = new HandlerThread("王灵生");
                handlerThread.start();

                //将 mHandler 与 Thread 相关联
                mHandler = new Handler(handlerThread.getLooper()){
                    @Override
                    public void handleMessage(Message msg) {
                        super.handleMessage(msg);

                        Log.d(TAG, "handleMessage: 当前子线程是----->" + Thread.currentThread());
                    }
                };
                mHandler.sendEmptyMessage(1);


            }
        });

    }

Handler是一个包含Looper的Thread 可以使用这个Looper创建Handler,HandleMessage所在的线程就是HandlerThread的子线程。


  • 子线程和子线程通信

第一个子线程里创建handler,开启Looper轮训,第二个子线程当中调用这个handler发送消息就可以了。

Button button_child_to_child;
    Button button_child_to_child2;

    private Handler childHandler;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        button_child_to_child = (Button) findViewById(R.id.button_child_to_child);
        button_child_to_child.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //创建第一个子线程
                new Thread(new Runnable() {
                    @Override
                    public void run() {

                        Looper.prepare();

                        childHandler = new Handler(){
                            @Override
                            public void handleMessage(Message msg) {
                                super.handleMessage(msg);

                                System.out.println("这个消息是从-->>" + msg.obj + "过来的,在" + "btn的子线程当中" + "中执行的");

                            }
                        };
                        Looper.loop();  //开始轮询

                    }
                }).start();
            }
        });


        button_child_to_child2 = (Button) findViewById(R.id.button_child_to_child2);
        button_child_to_child2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //第二个子线程 发送消息
                new Thread(new Runnable() {
                    @Override
                    public void run() {

                        //发送消息
                        Message message = childHandler.obtainMessage();
                        message.obj = "btn2当中子线程";
                        childHandler.sendMessage(message);

                    }
                }).start();

            }
        });






  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

阿姨不可以嘛

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值