android消息处理机制

来源:互联网 发布:数控车编程手机版apk 编辑:程序博客网 时间:2024/04/20 16:31

今天晚上,觉得没事,就看了一下android的消息处理机制,下面是本人的一点观点,当然有一些是别人的东西,顺便借鉴一下。。。

  我们知道,windows系统存在消息循环系统,通过观察,我们不难发现,android系统的消息循环机制很大程度上借鉴了windows的消息循环机制,Android通过Looper、Handler来实现消息循环机制,Android消息循环是针对线程的(每个线程都可以有自己的消息队列和消息循环)。

   Android系统中Looper负责管理线程的消息队列和消息循环,Android系统的消息队列和消息循环都是针对具体线程的,一个线程可以存在(当然也可以不存在)一个消息队列和一个消息循环(Looper),特定线程的消息只能分发给本线程,不能进行跨线程,跨进程通讯。但是创建的工作线程默认是没有消息循环和消息队列的,如果想让该线程具有消息队列和消息循环,需要在线程中首先调用Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环。也许有人会问,问什么在UI线程中,我们没有可以去调用Looper.prepare(),也可以进入消息循环,其实,在ui主线程一开始建立时,系统就自动调用Looper.prepare(),等待消息循环。

看下面的一个示例:

public class shili extends Activity {
 private TextView text;
 private static final int TAG = 1;
 private Handler han = new Handler() {

  @Override
  public void handleMessage(Message msg) {
   switch (msg.what) {
   case TAG:
    shili.this.text.setText("当前时间是:" + msg.obj);
    break;

   }
   super.handleMessage(msg);
  }

 };

 private class time implements Runnable {

  @Override
  public void run() {
   Message msg = shili.this.han.obtainMessage(TAG,
     new SimpleDateFormat("yyyy-MM-dd hh:MM:ss")
       .format(new Date()));
                 han.sendMessage(msg);
  }
 }

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
  super.setContentView(R.layout.clock);
  this.text=(TextView)super.findViewById(R.id.info);
 
 }

}

示例很简单,就是把新开辟的一个线程中的时间显示在主线程的控件上。有人也许会问,问什么不在主线程中直接写呢,确实,如果只是获得时间的话,我们完全可以在主线程中获得,然后,显示在控件上。但是,别忘了,如果我们要在控件上显示的是从网络获得图片和文字数据呢,难道还要直接写吗?我们知道,ui线程是不安全的 ,当我们的主线程队列,如果处理一个消息超过5秒,android 就会抛出一个 ANP(无响应)的消息,所以,我们需要把一些要处理比较长的消息,放在一个单独线程里面处理,把处理以后的结果,返回给主线程运行,就需要用的Handler来进行线程建的通信 

好了,回归正题,下面,我们看一下这种机制的实现原理,,为了,更好的了解Handler的机制,我们应该首先熟悉Android系统整个运行进程

下面是handler的工作图:

 

下面是Handler,Message,Message Queue 之间的关系图

 

 

 

这个图有4个地方关系到handlers

1, 主线程(Main thread)

2, 主线程队列(Main thread queue)

3,Hanlder

4,Message

上面的四个地方,主线程,和主线程的队列我们无需处理,所以,我们主要是处理Handler 和 Message 之间的关系.

我们每发出一个Message,Message就会落在主线程的队列当中,然后,Handler就可以调用Message绑定的数据,对主线程的组件进行操作.

作为handler接受的对象,我们有必要知道Message这个数据类型是个怎样的数据类型

public int what public int arg1 public int arg2 public Object obj 

从上面的表格可以看出,message 提供了一个对象来存储对象,而且,还提供了三个int字段用来存储少量int类型

当然,除了以上三个Message 自有的字段外,我们还可以通过setData(Bundle b),来存储一个Bundle对象,来存储更丰富的数据类型,例如,图片等等.

 

 

不好,学校这边快关门了,不能写了,明天有时间在续写

 

 

 

 

 

原创粉丝点击