浅析Handler消息传递机制

Android的异步消息处理机制:Handler消息传递机制。

浅析Handler消息传递机制_第1张图片
流程图
1、Message

Message是在线程之间传递的消息,它可以在内部携带少量的信息,用于在不同线程之间交换数据。

2、Handler

Handler主要是用于发送和处理消息。发送消息一般是使用Handler的sendMessage()方法,而发出的消息经过一系列地辗转处理后,最终会传递到Handler的handleMessage()方法中。

3、MessageQueue

MessageQueue是消息队列,主要用于存放所有通过Handler发送的消息。这部分消息会一直存在于消息队列中,等待被处理。每个线程中只会有一个 MessageQueue对象。

4、Looper

Looper是每个线程中的MessageQueue的管家,调用Looper的loop()方法后,就会进入到一个无限循环当中,然后每当发现MessageQueue中存在一条消息,就会将它取出,并传递到Handler的handleMessage()方法中。每个线程中也只会有一个Looper对象。

Handler的相关方法

void handleMessage(Message msg)
处理消息的方法,通常是用于被重写。

sendEmptyMessage(int what)
发送空消息
sendEmptyMessageDelayed(int what, long delayMillis)
指定延时多少毫秒后发送空信息

sendMessage(Message msg)
立即发送信息
sendMessageDelayed(Message msg)
指定延时多少毫秒后发送信息

final boolean hasMessage(int what)
检查消息队列中是否包含what属性为指定值的消息。
final boolean hasMessage(int what, Object object)
除了判断what属性,还需要判断Object属性是否为指定对象的消息。

示例

1、Handler写在主线程中
public class MainActivity extends AppCompatActivity {

    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0x123:
                    // 在这进行UI操作
                    break;
            }
        }
    };

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

        new Thread(new Runnable() {
            @Override
            public void run() {
                // 发送空消息
                handler.sendEmptyMessage(0x123);
            }
        }).start();
    }
}

在主线程中,因为系统已经初始化了一个Looper对象,所以我们直接创建Handler对象就可以进行信息的发送与处理了。

2、Handler写在子线程中

XML布局文件



    

    

Java代码

public class MainActivity extends AppCompatActivity {

    private EditText number;
    private Button sure;

    private MyThread myThread;

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

        myThread = new MyThread();
        myThread.start();

        initView();
    }

    private void initView() {
        number = (EditText) findViewById(R.id.number);
        sure = (Button) findViewById(R.id.sure);

        sure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message message = new Message();
                message.what = 0x123;
                Bundle bundle = new Bundle();
                bundle.putInt("number", Integer.parseInt(number.getText().toString()));
                // 设置数据
                message.setData(bundle);
                // 发送消息
                myThread.handler.sendMessage(message);
            }
        });
    }

    class MyThread extends Thread {

        Handler handler;

        @Override
        public void run() {
            // 创建Looper对象
            Looper.prepare();
            handler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    if (msg.what == 0x123) {
                        int number = msg.getData().getInt("number");
                        Toast.makeText(MainActivity.this
                                , "你输入的数字是:" + number
                                , Toast.LENGTH_SHORT).show();
                    }
                }
            };
            // 启动Looper
            Looper.loop();
        }
    }
}

如果Handler写在子线程中,就需要自己创建一个Looper对象了。
1、直接调用Looper.prepare()方法即可为当前线程创建Looper对象,而它的构造器会创建配套的MessageQueue。
2、创建Handler对象,重写handleMessage( )方法就可以处理来自于其他线程的信息。
3、调用Looper.loop()方法启动Looper。

参考

《第一行代码》
3.3 Handler消息传递机制浅析

你可能感兴趣的:(浅析Handler消息传递机制)