博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android之Looper
阅读量:6071 次
发布时间:2019-06-20

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

hot3.png

        Looper:循环器,是一个用于使线程运行一个消息(Message)循环的类。线程默认没有关联的消息循环,在创建它之前,在将要运行循环的线程中调用prepare方法,然后loop方法会处理消息直到循环结束。

        绝大多数消息循环是通过Handler类来Looper交互的。

        下面是实现了Looper的线程的一个典型例子,使用分离的prepare方法和loop方法来创建一个用于跟Looper沟通的初始Handler。

class LooperThread extends Thread {    public Handler mHandler;    public void run() {        Looper.prepare();        mHandler = new Handler() {            public void handleMessage(Message msg) {                // process incoming messages here            }        };             Looper.loop();    }}

        先看准备工作的prepare方法:

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

        每条线程只能绑定一个Looper,否则会抛出RuntimeException异常。如果不调用prepare方法,sThreadLocal.get()就会返回null。注意这是个静态方法,在最后一行中绑定了一个做为Looper的线程。怎么绑定的呢,看看Looper的一个私有无参构造方法:

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

        构造方法里初始化了一个消息队列、一个运行状态的标志以及绑定一个线程(创建者所在的线程)。prepare方法给了一个在真正的循环开始之前,参照Looper创建一个Handler的机会。注意:在run方法中初始化Handler之前,必须调用Looper.prepare(),不然会抛出一个运行时异常,因为Handler需要一个从Looper得到的消息队列(即构造方法里面的mQueue)。调用prepare方法后一定要调用loop方法,并且调用quit方法退出循环。

        接下来,看看在当前线程里运行一个消息队列的loop方法,用完后一定要调用quit方法结束循环:

public static final void loop() {    Looper me = myLooper();    MessageQueue queue = me.mQueue;    while (true) {        Message msg = queue.next(); // might block        if (msg != null) {            if (msg.target == null) {                // No target is a magic identifier for the quit message.                return;            }            msg.target.dispatchMessage(msg);            msg.recycle();        }    }}

        高潮来了,上面说过,Looper的mQueue是Handler使用的消息队列,loop方法启动一个死循环从队列中获取数据,当队列中没有数据时,queue.next()会阻塞。当有数据时,msg.target(即Handler)就会调用dispatchMessage方法,进而调用Handler的handleCallback或者handlerMessage方法。从这些也可以知道,如果Handler是在子线程的run方法中创建(之前必须调用Looper.prepare())的,那么这个Handler的handleMessage或者handleCallback方法就是运行在子线程的。

转载于:https://my.oschina.net/u/272863/blog/93721

你可能感兴趣的文章
spark高级排序彻底解秘
查看>>
ylbtech-LanguageSamples-PartialTypes(部分类型)
查看>>
福建省促进大数据发展:变分散式管理为统筹集中式管理
查看>>
开发环境、生产环境、测试环境的基本理解和区别
查看>>
tomcat多应用之间如何共享jar
查看>>
Flex前后台交互,service层调用后台服务的简单封装
查看>>
技术汇之物联网设备网关技术架构设计
查看>>
OSX10.11 CocoaPods 升级总结
查看>>
深入浅出Netty
查看>>
3.使用maven创建java web项目
查看>>
笔记本搜索不到某一AP广播的SSID,信道的原因
查看>>
基于Spring MVC的异常处理及日志管理
查看>>
MediaBrowserService 音乐播放项目《IT蓝豹》
查看>>
MySQL入门12-数据类型
查看>>
Windows Azure 保留已存在的虚拟网络外网IP(云服务)
查看>>
修改字符集
查看>>
HackTheGame 攻略 - 第四关
查看>>
js删除数组元素
查看>>
带空格文件名的处理(find xargs grep ..etc)
查看>>
华为Access、Hybrid和Trunk的区别和设置
查看>>