题1请阐述下在单线程模型中Message,Handler,Message Queue,Looper

首先要理解几个关键概念:
1> MessageQueue: MessageQueue->消息队列,是一种数据结构,先进先出,是存放消息的地方.每一个线程最多
只可以拥有一个MessageQueue数据结构.通常使用一个Looper对该线程的MessageQueue进行管理.除了主线程
之外,在创建一个线程的时候并不会自动创建其MessageQueue,而主线程在创建的时候,会创建一个默认的Looper
对象,而Looper对象的创建,会自动创建一个MessageQueue对象.而其他的非主线程,不会自动创建Looper,通过调用
Looper.prepare()方法来手动创建.

2> Message: 消息对象,MessageQueue中存放的对象,一个MessageQueue可以存放多个Message.
Message实例对象的取得,通常使用Message类的静态方法obtain(),它的创建并不一定会创建一个新的实例,而会是先
尝试从MessagePool(消息池)中看有没有可用的Message实例,存在则直接取出这个实例对象.如果MessagePool中没有可用
的Message实例,则才用给定的参数创建一个Message对象.当调用removeMessage()的时候,会将Message从MessageQueue中移除掉,
并加入到MessagePool(消息池)当中.除了上面这种方法,也可以使用Handler实例的obtainMessage()方法获取一个Message实例.

3> Looper MessageQueue的管理者.每一个MessageQueue都不能脱离Looper而存在,Looper的创建则是通过prepare()方法实现的.
同时每一个Looper对象和一个线程关联.通过调用Looper.myLooper()可以获得当前线程的Looper对象.创建一个Looper对象的时候,
会同时创建一个MessageQueue对象.除了主线程有默认的Looper,其他线程默认没有MessageQueue对象的,所以不能接受Message.如果
需要接收Message,则需要自定义Looper对象,通过调用Looper的prepare()方法,这样该线程就有了自己的Looper对象和MessageQueue
数据结构了.Looper从MessageQueue中取出Message后,交由Handler的handleMessage进行处理.处理完成之后,调用Message.recycle()
将其放入MessagePool当中.

4> Handler-> 消息处理者,handler负责将要传递的消息封装成Message,通过调用handler对象的obtainMessage()来实现.
将消息传递给Looper,这是通过handler的sendMessage()方法实现的.然后由Looper将Message放入的MessageQueue消息队列中.
当Looper对象看到MessageQueue中含有Message,就将其广播出去.该handler对象收到消息后,调用相应的handler对象的handleMessage()
方法对其进行处理.

这里有一张图解

简单来说Handler获取当前线程中的Looper对象,Looper是以一种轮循的方法从存放Message的MessageQueue中取出Message.还有Handler
负责Message的分发和处理.Looper是Handler和Message之间的桥梁,程序组件首先是通过Handler把消息传递给Looper,Looper将消息存放
入队列,Looper也把队列中的消息广播给所有的Handler,Handler接收到消息之后,调用handleMessage()方法中的得到的单个消息进行处理.

下面是一个简单的Demo.模拟线程发送消息和处理消息

package com.dream.fioman.fioman06_handlerandlooper;

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

public class MainActivity extends AppCompatActivity {
    private TextView tvShow;
    private Button btnTest;
    private Button btnTest2;
    private Handler handler;
    private Button btnText3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tvShow = (TextView) findViewById(R.id.textView);
        btnTest = (Button) findViewById(R.id.button);
        btnTest2 = (Button) findViewById(R.id.button2);
        btnText3 = (Button) findViewById(R.id.button3);

        /**
         * 主线程给自己发送Message
         */
        btnTest.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Looper looper = Looper.getMainLooper();  //主线程的Looper对象
                //这里以主线程的Looper对象创建了MessageQueue对象,所以这个handler发送的消息会传递给主线程的MessageQueue.
                handler = new MyHandler(looper);
                handler.removeMessages(0);
                //构建Message对象
                //第一个参数是int类型的消息代号,第二个第三个参数没有什么意义,第四个参数需要封装的对象.
                Message msg = handler.obtainMessage(1, 1, 1, "主线程发送消息了");

                handler.sendMessage(msg);
            }
        });

        /**
         * 子线程给主线程发送消息
         */
        btnTest2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread() {
                    @Override
                    public void run() {
                        Looper looper = Looper.getMainLooper();//主线程的Looper对象
                        //这里以主线程的Looper对象创建了handler,所以这个handler发送的Message会被传给主线程的MessageQueue
                        handler = new MyHandler(looper);
                        Message msg = handler.obtainMessage(1, 1, 1, "子线程发送消息!");

                        handler.sendMessage(msg);
                    }
                }.start();
            }
        });

        /**
         *  主线程给子线程发送消息
         */
        btnText3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //这里handler的实例化在子线程中,子线程启动的时候就已经实例化了.先启动线程
                new Thread() {
                    @Override
                    public void run() {
                        //创建该线程的Looper对象,用于接收消息
                        Looper.prepare();
                        //注意了这里的handler是定义在主线程中的哦,开始的时候实例化不了,因为该线程的Looper对象还不存在呢.
                        //现在可以实例化了,Looper.myLooper()获得该线程的Looper对象了
                        handler = new ThreadHandler(Looper.myLooper());
                        //下面开始循环,轮循消息队列,一有消息就取出来.
                        Looper.loop();
                    }
                }.start();
            }
        });

        Message msg = handler.obtainMessage(1, 1, 1, "主线程发送的消息.");
        handler.sendMessage(msg);
    }

    class ThreadHandler extends Handler {
        public ThreadHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            //这里对该线程中MessageQueue中的Message进行处理,这里我们在返回给主线程一个消息
            handler = new MyHandler(Looper.getMainLooper());

            Message msg2 = handler.obtainMessage(1, 1, 1, "子线程收到:" + msg.toString());

            handler.sendMessage(msg2);
        }
    }

    class MyHandler extends Handler {
        public MyHandler(Looper looper) {
            super(looper);
        }
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            tvShow.setText("我是主线程Handler,收到了消息: "+msg.toString());
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值