Android Handler 的消息传递机制

来源:互联网 发布:用友软件官方网 编辑:程序博客网 时间:2024/05/16 02:44

Handler消息传递机制

我们知道当一个Andorid程序第一次启动时,Andorid会调用一条主线程,用这条主线程来负责管理UI组件,所以我们也称它为UI线程。并且Andorid平台只允许UI线程来管理Activity中的UI组件。这样导致了新启动的线程没办法动态的改变系统中的UI组件,为了解决这个麻烦 Andorid使用了Handler消息传递机制。


Handler的主要作用

  • 在新启动的线程中发送消息
  • 在主线程中获取、处理消息

Handler包含了如下方法用来处理消息:

void handlerMessage(Message msg):处理消息的方法final boolean hasMessage(int what):查看消息队列中what指定值时候存在final boolean hasMessage(int what, Object object):查看消息队列中时候有what和object指定值得消息Message obtainMessage():获取消息sendEmptyMessage(int what):发送空消息,其中what是属性

来看一个Handler实例

import android.os.Handler;import android.os.Message;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.content.Intent;import android.util.Log;import android.view.View;import android.app.Activity;import android.widget.Button;import android.widget.Toast;import java.util.Timer;import java.util.TimerTask;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.first);        //创建一个Handler对象,重写handleMessage方法        final Handler myHandler =  new Handler(){            @Override            public void handleMessage(Message message){            //这里来写要让系统做什么                if (message.what == 0x1233){                    Log.v("Tag", "12331");                }            }        };        //定义一个计时器,周期性的发送空消息        new Timer().schedule(new TimerTask() {            @Override            public void run() {            //what属性是估计这么设置的,当然你也可以随意设置                myHandler.sendEmptyMessage(0x1233);            }        },0,200);    }}

程序的结果:

03-09 21:23:38.233 4177-4177/com.example.administrator.itentlearn V/Tag: 1233103-09 21:23:38.436 4177-4177/com.example.administrator.itentlearn V/Tag: 1233103-09 21:23:38.638 4177-4177/com.example.administrator.itentlearn V/Tag: 1233103-09 21:23:38.838 4177-4177/com.example.administrator.itentlearn V/Tag: 1233103-09 21:23:39.038 4177-4177/com.example.administrator.itentlearn V/Tag: 1233103-09 21:23:39.239 4177-4177/com.example.administrator.itentlearn V/Tag: 1233103-09 21:23:39.439 4177-4177/com.example.administrator.itentlearn V/Tag: 12331

当然你也可以用他来修改UI组件,直接写在handleMessage方法中就可以。
注意:在Androdi中新线程想要修改UI组件只有通过Handler重写handleMessage方法!


Andorid中文API:Handler
Handler的工作原理
首先介绍一下Handler的几个工作组件:

  • Message:Handler用来接收和处理消息的对象
  • Looper:每个线程都拥有一个Looper,它的作用是负责读取MessageQueue中的消息,每当读到消息就传递给Handler来处理
  • MessageQueue:消息队列,存取方式是先进先出,每当创建一个Looper对象时,在Looper的对象中会自动创建一个MessageQueue对象。

大家来看源码:

private Looper(){    mQueue = new MessageQueue();    mRun = true;    mThread = Thread.currentThread();}

这个构造器的修饰符是privata,所以不能直接创建这个Looper对象。要创建Looper对象要通过调用它的prapare()方法。

public static final void prepare(){    if(sThreadLocal.get() != null){        throw new RuntimeException("Only one Looper may be created per thread");    }    sThreadLocal.set(new Looper());}

所以Handler的工作原理是这样的:

Hanldler首先发送或接受消息,在发送消息的时候,消息被送到指定的MessageQueue.而MessageQueue是由Looper来负责管理的,Looper使用方法不断的从MessageQueue中取出消息,并且把消息发给对应的Handler来处理。

总而言之就是这三个的各自作用如下:

-Looper:每个线程只有一个Looper,它负责管理MessageQueue,不断的从中读取消息,并且发给对应的Handler来处理
-MessageQueue:由Looer负责管理,采用先进先出的方式来管理Queue
-Handler:能够发送消息去MessageQueue,并且能够处理来自Looper的消息

0 0