android 中的消息机制

Android 的消息机制

在android 中,我们通常把UI页面所在的线程叫做主线程,如果主线程执行某一项耗时操作超过5秒中,程序就会报ANR异常。到那时我们在实际开发的过程中,不可避免的会进行耗时操作,比如加载网络图片,加载网络数据等,此时我们通常会将耗时操作放在子线程中执行,子线程执行完成后剑门关数据或结果发送给主线程,这个时候就用到了android 的消息机制。

消息队列

Android应用程序每启动一个线程,都为其创建一个消息队列,然后进入到一个无线循环之中,然后不断检查队列中是否有新消息需要处理,如果没有,线程就会进入睡眠状态,繁殖会对消息进行分发处理。

消息机制的核心类

android 的消息处理有三个核心类:Looper,Handler和Message。(消息队列被封装到Looper里面,我们不会直接与消息队列打交道)。

消息(Message):存放在消息队列中,被Looper循环取出执行,消息可以携带数据,并制定操作;

Handler:可以向消息队列中存放消息;

Looper:无线循环地从消息队列中获取消息并执行。

(1)Message类

android.os.Message的主要功能是进行消息的封装,并且同时可以指定消息的操作形式。

No.

变量或方法

类型

描述

1

public int what

变量

用于定义此Message属于何种操作

2

public Object obj

变量

用于定义此Message传递的信息数据

3

public int arg1

变量

传递一些整型数据时使用,一般很少使用

4

public int arg2

变量

传递一些整型数据时使用,一般很少使用

5

public Handler getTarget()

普通

取得操作此消息的Handler对象

(2)Handler类常用方法

Message对象封装了所有的消息,而这些消息的操作就需要android.os.Handler类完成

No.

方法

类型

描述

1

public Handler()

构造

创建一个新的Handler实例

2

public Handler(Looper looper)

构造

使用指定的队列创建一个新的Handler实例

3

public final Message obtainMessage(int what, Object obj)

普通

获得一个Message对象

4

public final Message obtainMessage(int what, int arg1, int arg2, Object obj)

普通

获得一个Message对象

5

public void handleMessage(Message msg)

普通

处理消息的方法,子类要覆写此方法

6

public final boolean hasMessages(int what)

普通

判断是否有指定的Message

7

public final boolean hasMessages(int what, Object object)

普通

判断是否有指定的Message

8

public final void removeMessages(int what)

普通

删除掉指定的Message

9

public final void removeMessages(int what, Object object)

普通

删除掉指定的Message

10

public final boolean sendEmptyMessage(int what)

普通

发送一个空消息

11

public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis)

普通

在指定的日期时间发送消息

12

public final boolean sendEmptyMessageDelayed(int what, long delayMillis)

普通

等待指定的时间之后发送消息

13

public final boolean sendMessage(Message msg)

普通

发送消息

(3)Handler的使用

通过Handler对象我们可以封装Message对象,然后通过sendMessage(msg)把Message对象添加到消息队列中;

当MessageQueue(消息队列)循环到该Message时,就会调用该Message对象对应的handler对象的handleMessage()方法对其进行处理;

由于是在handleMessage()方法中处理消息,因此我们需要编写一个类继承Handler,然后重写handleMessage()处理我们需要的操作。

class MyHandler extends Handler {        

@Override         public void handleMessage(Message msg) {    

        // 操作         } }

实例:

实现计时器功能

package com.zhidi.clock;

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.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    //1、定义一个what标记、一个Handler对象,一个初始为10的int数据。
    public static final int WHAT_MAIN = 1;
    private Handler mainHandler;

    private int count=10;

    private Button bt_start;
    private TextView tv_show;

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

        init();

        //4、实例化主线程的Handler
        mainHandler = new MyHandler();

        bt_start.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {
                //5、启动子线程。
                new Thread(new ChildThread()).start();
            }
        });

    }

    private void init(){
        bt_start=(Button)findViewById(R.id.bt_start);
        tv_show=(TextView)findViewById(R.id.tv_show);
    }

    /**
     * 2、创建一个子线程类,extends Thread,重写run()实现倒数计数器,并把Message传递给主线程。
     * @author Administrator
     */
    class ChildThread extends Thread{
        @Override
        public void run() {
            Looper.prepare();// 初始化Looper

            //实现倒数计数器
            while(count>=0){
                try {
                    Message toMain = mainHandler.obtainMessage();// 创建Message
                    toMain.obj = count;//设置显示文字
                    toMain.what = WHAT_MAIN; //设置主线程操作的状态码
                    mainHandler.sendMessage(toMain);

                    count--;

                    Thread.sleep(1000);// 延迟1秒
                } catch (Exception e) {
                }
            }
            Looper.loop();//启动该线程的消息队列
        }
    }

    /**
     * 3、创建一个自定义Handler类,extends Handler,重写handleMessage(Message),判断what标记更新UI。
     * @author Administrator
     *
     */
    class MyHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {//判断what操作
                case WHAT_MAIN:// 设置主线程的操作类
                    tv_show.setText(msg.obj.toString());//设置文本内容
                    break;
            }
        }
    }


}
 

猜你喜欢

转载自blog.csdn.net/u011897782/article/details/81206105