Android学习笔记(7)————Android中的消息机制

来源:互联网 发布:垫江网络建设djrckj 编辑:程序博客网 时间:2024/05/16 11:30

/********************************************************************************************
 * author:conowen@大钟                                                                                                                          
 * E-mail:conowen@hotmail.com                                                                                                             
 * http://blog.csdn.net/conowen                                                                                                              
 * 注:本文为原创,仅作为学习交流使用,转载请标明作者及出处。     
 ********************************************************************************************/


1、Android管理线程的类



1.1、Message———MessageQueue的存放对象,各个线程之间交流的信息,线程处理完数据之后,需要更新UI,则发送Message给UI线程(即主线程)

1.2、MessageQueue———消息队列,用来存放Handler发送过来的消息。当然,存放Message并非实际意义的保存, 而是将Message以链表的方式串联起来的,等待Looper的抽取。

1.3、Looper———消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue就需要一个Looper。(也就是说一个Looper里面有一个Message Queue)

1.4、Handler———担当处理者角色,负责发送新消息到MessageQueue里面和处理消息,通知主线程更新UI


简述一下Android的消息传递过程

          当子线程要发送Message给主线程时,首先要为当前线程创建一个Handler类对象,由Handler调用相应的方法,将需要发送的Message发送到MessageQueue(消息队列)中,当Looper发现MessageQueue中有未处理的消息时就会将此消息广播出去,此时主线程的Handler接收到此Message时,就会调用相应的方法来处理这条信息,完成主界面更新。(Looper与Handler的详细可参看第2、第3点)

注:

a.一个线程只能有一个Looper对象,它是一个ThreadLocal,但是一个线程或者一个Looper可以对应多handler。

b.每一个Looper内部都有一个MessageQueue(消息队列),loop()方法被调用后,线程开始不断从队列中取出消息执行

c.Looper使一个线程变成Looper线程。

Looper Thread、Message Queue、Handler、Looper的大概架构图。



2、为线程创建Looper

          除了主线程(main thread或称UI thread),Android系统启动会自动地位它建立一个Message Queue,,当然地,也同时地建立了Looper。其他线程的话,Android系统不会自动为其建立Message Queue的,要用户手动建立。一旦建立了Looper,Looper内部的Message Queue就会自动地建立了。

2.1、主线程

当Android系统启动主线程(UI线程)时,应用程序就会自动进入线程的main函数中,然后自动为主线程创建Looper

过程代码如下

Looper.prepareMainLooper();   //建立消息队列,设置主LooperLooper.loop();  //启动消息循环,然后才能运作起来//此两段代码都在主线程中的main函数中

2.2、其它线程

其他线程Looper就要用户自己手动创建了。

具体方法如下:

在其他线程的run方法中里面写下如下代码

public void run() {Looper.prepare();   //创建消息队列 /**此处是线程的核心代码,用户自定义即可/Looper.loop();    //启动消息循环}

若要查看当前线程的Looper,调用Looper.myLooper();方法即可


Looper的其他方法

2.2.1、Looper.myLooper()得到当前线程Looper对象。


2.2.2、Looper.getThread()得到Looper对象所属线程。


2.2.3、Looper.quit()方法结束Looper循环。


3、Handler的使用

首先应该知道的是Handler的异步消息处理,异步是指,发送消息处理消息不在同一时间。


         首先Handler在其他线程中发出一个Message到消息队列中,而且发送消息的函数方法立刻返回,另外,在创建这个Handler的线程中,Looper将Message从消息队列中取出来,由Handler调用方法来处理消息。


举一个常见的例子:


在主线程中,创建一个Handler,然后在其他耗时比较长的线程中由Handler发出一个Message,同时,主线程中有Handler的处理函数,Handler会处理这个发送过来的消息,从而更新UI。(因为主线程中系统已经自动地创建了一个Looper,(也就是说主线程也是一个Looper线程),所以不用用户手动地创建Looper了)






Handler创建的时候,要关联一个Looper,默认是关联当前线程的Looper,当然了,也可以自己设定。

由于一个线程可以有多个Handler(Handler只有一个Looper),因此我们可以在同一个线程中创建多个Handler,如

public class LooperThread extends Thread {    private Handler myhandler1;    private Handler myhandler2;    @Override    public void run() {        // 当前线程变为Looper线程        Looper.prepare();        // 实例化两个handler        myhandler1 = new Handler();        myhandler2 = new Handler();                // 开始循环处理消息队列        Looper.loop();    }}

发送消息:

Handler发送消息的方法如下,可以在任意线程中发送消息。

post(Runnable),postAtTime(Runnable, long),postDelayed(Runnable, long),sendEmptyMessage(int),sendMessage(Message),sendMessageAtTime(Message, long), sendMessageDelayed(Message, long)


         发送的是Runnable对象与Message,事实上,Handler发送Runnable对象时,已经把其封装为Message了。所以Handler发送的都是Message。

Message发送的时候,已经附带着Handler的信息,也就是说从一个Message对象可以知道它是哪一个Handler的,所以Looper执行Message时,就知道该Message是哪个Handler发出的。

如定义一个Message msg

然后message.target方法返回的是发送这个的Message的Handler对象。


消息处理:


Handler是在(与自己关联的)线程中处理消息的,主要有两个方法。(一个线程可以有多个Handler)

void    dispatchMessage(Message msg) //Handle system messages here.void      handleMessage(Message msg)   //Subclasses must implement this to receive messages.
处理消息,其实也就是通知主线程更新UI



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 医师面试题号忘了写怎么办 淘宝买东西东西被别人拿走了怎么办 9个月宝宝上肢支撑不好怎么办 宝宝快十一个月了留口水怎么办 两岁宝宝不会自己登着大小便怎么办 小新家的房子被炸了房贷怎么办 怀孕8个月感冒鼻窦炎头疼怎么办 买的全身镜下面的框子坏了怎么办 单位上司姐姐每天要接我上班怎么办 企业微信公众号中的文章边框怎么办 怎么办我在数学答题卡上画了分割线 游泳的时候泳裙飘起来怎么办 两岁宝宝误服了酵素梅怎么办 人被困在山洞里没有氧气怎么办? 一个人太爱你可你不爱他怎么办 牙齿还没掉又长了新牙齿怎么办 两岁宝宝牙齿发黑烂牙怎么办 怀孕八个月被小孩压到肚子了怎么办 在花场上班客人约我出去玩怎么办 小天才电话手表开不了机怎么办 黑色笔芯弄在白色衣服上怎么办 su文件打开是意外的格式怎么办 su卡的动一下就卡怎么办 犀牛vary渲染的太曝光了怎么办 脑子老是乱想幻想控制不住怎么办 猫抓了破了点皮怎么办 小孩子喜欢玩别人家的玩具怎么办 孩子把别人家的玩具玩坏了怎么办 小新和爸妈一起睡觉那他们怎么办 ps画纸画的时候一直在移动怎么办 宝宝磕碰到家具上鼻梁碰破该怎么办 月经推迟11天了怎么办孕测棒单杠 小孩子不小心把蜡笔吃一点怎么办 线切割切割的工件表面有条纹怎么办 苹果手机不能用流量更新吃鸡怎么办 吃鸡更新成雨林如果内存不够怎么办 绝地求生刺激战场背包满了怎么办 绝地求生刺激战场模拟器满了怎么办 绝地求生刺激战场电脑版满了怎么办 绝地求生手游模拟器注册上限怎么办 绝地求生电脑模拟器已达上限怎么办