Android基础之Handler机制(四)Looper源码分析

基于8.0.0源码

##定义##

 Class used to run a message loop for a thread.  Threads by default do not have a message loop associated with them; to create one, call {@link #prepare} in the thread that is to run the loop, and then {@link #loop} to have it process messages until the loop is stopped.

个人理解

- Looper的作用是不断的从MessageQueue中取出消息传给宿主Handler来处理. 主线程不需要我们做操作,系统已经做好处理.
- 如果是新建一个线程需要使用Looper的话, 需要先调用prepare()方法来初始化Looper,然后调用loop()方法来开启循环.

方法细节

构造方法

  • 我们可以看到构造方法是私有的,就是不允许通过构造来创建.

      private Looper(boolean quitAllowed) {
      	//创建MessageQueue队列
      	mQueue = new MessageQueue(quitAllowed);
      	//得到当前的线程
      	mThread = Thread.currentThread();
      }
    
  • 一个线程只能有一个Looper实例

初始化方法

  • 不能通过构造方法来创建对象,那我们看系统提供了哪些方法

  • static void prepare()

      //在子线程中使用Looper的时候调用
     	public static void prepare() {
      	prepare(true);
      }
    
      private static void prepare(boolean quitAllowed) {
      	if (sThreadLocal.get() != null) {
          	throw new RuntimeException("Only one Looper may be created per thread");
      	}
      	//创建Looper
      	sThreadLocal.set(new Looper(quitAllowed));
      }
    
  • static void prepareMainLooper()

      //主线程即UI线程开启的时候系统已经创建了主线程的Looper,这里不需要我们去调用这个方法
       public static void prepareMainLooper() {
      	prepare(false);
      	synchronized (Looper.class) {
          	if (sMainLooper != null) {
              	throw new IllegalStateException("The main Looper has already been prepared.");
          	}
          	sMainLooper = myLooper();
      	}
      }
    

工作线程获取Looper以及MessageQueue###

//返回当前工作线程的looper,如果当前线程没有初始化looper则会返回空
public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}

//返回当前线程正在运行的looper创建的MessageQueue,否则会抛出空指针异常
public static @NonNull MessageQueue myQueue() {
    return myLooper().mQueue;
}

loop 方法

  • Looper就是通过此方法不停的从MessageQueue中取出Msg,然后再传递给宿主Handler来处理

      public static void loop() {
      //得到当前线程的looper
      final Looper me = myLooper();
      //looper没有初始化,抛出异常
      if (me == null) {
          throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
      }
      //得到当前线程的MessageQueue
      final MessageQueue queue = me.mQueue;
    
      //得到当前线程的唯一标识 
      final long ident = Binder.clearCallingIdentity();
      
      for (;;) {
      	//取出队列中消息
          Message msg = queue.next();
          if (msg == null) {
              // No message indicates that the message queue is quitting.
              return;
          }
    
      	....
          try {
      		//把消息分发给Handler,Handler来处理消磁
              msg.target.dispatchMessage(msg);
              end = (slowDispatchThresholdMs == 0) ? 0 : SystemClock.uptimeMillis();
          } finally {
              if (traceTag != 0) {
                  Trace.traceEnd(traceTag);
              }
          }
          ....
      	//消息被回收
          msg.recycleUnchecked();
      }
    

    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值