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

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

hot3.png

Looper主要是prepare()和loop()两个方法:

    1.首先看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(true));  }

    sThreadLocal是一个ThreadLocal对象,可以在一个线程中存储变量。可以看到,在第5行,将一个Looper的实例放入了ThreadLocal,并且2-4行判断了sThreadLocal是否为null,否则抛出异常。这也就说明了Looper.prepare()方法不能被调用两次,同时也保证了一个线程中只有一个Looper实例~相信有些哥们一定遇到这个错误。

    2.下面看Looper的构造方法:

private Looper(boolean quitAllowed) {      mQueue = new MessageQueue(quitAllowed);  //创建了一个MessageQueue(消息队列)。    mRun = true;      mThread = Thread.currentThread();  }

    在构造方法中,创建了一个MessageQueue(消息队列)。

    3.然后我们看loop()方法:

public static void loop() {      final Looper me = myLooper();      if (me == null) {          throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");    }      final MessageQueue queue = me.mQueue;          // Make sure the identity of this thread is that of the local process,      // and keep track of what that identity token actually is.      Binder.clearCallingIdentity();          final long ident = Binder.clearCallingIdentity();      for (;;) {          Message msg = queue.next(); // might block          if (msg == null) {              // No message indicates that the message queue is quitting.              return;          }          // This must be in a local variable, in case a UI event sets the logger          Printer logging = me.mLogging;          if (logging != null) {              logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what);          }          msg.target.dispatchMessage(msg);          if (logging != null) {          logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);      }          // Make sure that during the course of dispatching the      // identity of the thread wasn't corrupted.      final long newIdent = Binder.clearCallingIdentity();      if (ident != newIdent) {          Log.wtf(TAG, "Thread identity changed from 0x"          + Long.toHexString(ident) + " to 0x"          + Long.toHexString(newIdent) + " while dispatching to "          + msg.target.getClass().getName() + " "          + msg.callback + " what=" + msg.what);      }          msg.recycle();      }  }

    第2行:

public static Looper myLooper() { //直接返回sThreadLocal存储的Looper实例,如果me为null则抛出异常,也就是说looper方法必须在prepare方法之后运行    return sThreadLocal.get(); }

    第6行:拿到该looper实例中的mQueue(消息队列)

    13到45行:就进入了我们所说的无限循环。

    14行:取出一条消息,如果没有消息则阻塞。

    27行:使用调用 msg.target.dispatchMessage(msg);把消息交给msg的target的dispatchMessage方法去处理。Msg的target是什么呢?其实就是handler对象,下面会进行分析。

    44行:释放消息占据的资源。

Looper主要作用:

    1、与当前线程绑定,保证一个线程只会有一个Looper实例,同时一个Looper实例也只有一个MessageQueue。

    2、loop()方法,不断从MessageQueue中去取消息,交给消息的target属性的dispatchMessage去处理。

转载于:https://my.oschina.net/u/2320057/blog/640039

你可能感兴趣的文章
ASP.NET视频教程 手把手教你做企业论坛网站 视频教程
查看>>
[LeetCode] Meeting Rooms II
查看>>
从Swift学习iOS开发的路线指引
查看>>
Scribes:小型文本编辑器,支持远程编辑
查看>>
ssh 安装笔记
查看>>
3-继承
查看>>
海归千千万 为何再无钱学森
查看>>
vue2.0 仿手机新闻站(六)详情页制作
查看>>
JSP----九大内置对象
查看>>
Java中HashMap详解
查看>>
delphi基本语法
查看>>
260. Single Number III
查看>>
Hadoop生态圈-Kafka的完全分布式部署
查看>>
[MODx] Build a CMP (Custom manager page) using MIGX in MODX 2.3 -- 1
查看>>
jQuery自动完成点击html元素
查看>>
[算法]基于分区最近点算法的二维平面
查看>>
webpack多页应用架构系列(七):开发环境、生产环境傻傻分不清楚?
查看>>
笨办法学C 练习1:启用编译器
查看>>
树的总结--树的性质(树的深度) leetcode
查看>>
【Android游戏开发之六】在SurfaceView中添加组件!!!!并且相互交互数据!!!!...
查看>>