博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于Handler与异步消息处理循环的摘抄
阅读量:5965 次
发布时间:2019-06-19

本文共 2184 字,大约阅读时间需要 7 分钟。

  

  Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue 统一队列,终由Handler处理。

  Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现 handlerMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。          

     MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。 当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的, 等待Looper的抽取。

  Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此一个MessageQueue 需要一个Looper Thread:线程,负责调度整个消息循环,即消息循环的执行场所。

  Android系统的消息队列和消息循环都是针对具体线程的,一个线程可以存在(当然 也可以不存在)一个消息队列和一个消息循环(Looper),特定线程的消息只能分发给 本线程,不能进行跨线程,跨进程通讯。但是创建的工作线程默认是没有消息循环和 消息队列的,如果想让该线程具有消息队列和消息循环,需要在线程中首先调用 Looper.prepare()来创建消息队列,然后调用Looper.loop()进入消息循环。

public void run() {  

   Looper.prepare();//给线程创建一个消息循环  

  mHandler = new Handler() {    

       public void handleMessage(Message msg) {      // process incoming messages here     }   };

    Looper.loop();//使消息循环起作用,从消息队列里取消息,处理消息   }

}

  一个Message经由Handler的发送,MessageQueue的入队,Looper的抽取,又再一次地 回到Handler的怀抱,经过这一圈,将同步操作变成异步操作。 Handler的作用是把消息加入到特定的(Looper)消息队列中,并分发和处理该消息队列 中的消息。构造Handler的时候可以指定一个Looper对象,如果不指定则利用当前 线程的Looper创建。 一个Activity中可以创建多个工作线程或者其它的组件,如果这些线程或组件把它们 的消息放入Activity的主线程消息队列,那么该消息就会在主线程中处理了。 因为主线程一般负责界面的更新操作。 另外一个线程怎样把消息放入主线程的消息队列呢?是通过Handler对象,只要 Handler对象以主线程的Looper创建,那么调用Handler的sendMessage等接口,将 会把消息放入主线程的消息队列。

  在主线程(UI线程)里,如果创建Handler时不传入Looper对象,那么将直接使用主线程 的Looper对象(系统已经帮我们创建了);在其它线程里,如果创建Handler时不传入 Looper对象,那么,这个Handler将不能接收处理消息。

    new Thread(new Runnable() {                         

      @Override                            

     public void run() {                                

                                  Looper.prepare();                                

             Toast.makeText(LoginActivity.this,"ssss",Toast.LENGTH_SHORT).show();                               

              Looper.loop();                    

         }                     

    }).start();

  为线程准备好一个Looper(Looper.prepare),然后让这个Looper跑起来(Looper.loop) ,抽取Message,这样Handler才能正常工作。 因此,Handler处理消息总是在创建Handler的线程里运行。而我们的消息处理中, 不乏更新UI的操作,不正确的线程直接更新UI将引发异常。因此,需要时刻关心 Handler在哪个线程里创建的。

   以下,4种方式可以从其它线程访问UI线程:

  Activity.runOnUiThread(Runnable)

  View.post(Runnable)

  View.postDelayed(Runnable,long)

  Handler

  在post方法里,View获得当前线程(即UI线程)的Handler,然后将action对象post到 Handler里,它将传递过来的action对象包装成一个Message(Message的callback为 action),然后将其投入到UI线程的消息循环中。在Handelr再次处理该Message 时,直接调用runnable的run方法。 一个Looper对应一个MessageQueue 一个线程对应一个Looper 一个Looper可以对应多个Handler 不确定当前线程时,更新UI尽量调用Post方法。

转载于:https://www.cnblogs.com/likeshu/p/5390128.html

你可能感兴趣的文章
Linux系统中的文本处理工具
查看>>
IDE---Python IDE之Eric5在window下的安装
查看>>
python---LineReceiver实现记录服务器
查看>>
Mybatis调用Oracle中的存储过程和function
查看>>
telnet :No route to host
查看>>
基本安装lnmp环境
查看>>
yum源资料汇总
查看>>
7、MTC与MTV,http请求介绍
查看>>
logstash消费阿里云kafka消息
查看>>
第四节课作业
查看>>
EasyUI Calendar 日历
查看>>
unix 环境高级编程
查看>>
为数据库建立索引
查看>>
第二周作业-软件工作量的估计
查看>>
我的wordpress插件总结
查看>>
MAXIMO 快速查找实现
查看>>
Oracle——条件控制语句
查看>>
[Linux][Redis][05]Benchmark
查看>>
第一次作业-准备篇
查看>>
HDU1848 Fibonacci again and again
查看>>