zoukankan      html  css  js  c++  java
  • Android 线程 Looper.prepare()、Looper.loop() 使用

    优化项目过程中发现了一个非常Low的问题,整理一下。备忘:
    说问题之前先看下HandlerThread的定义
    一个封装了looper的线程:  

    Looper用于封装了android线程中的消息循环。默认情况下一个线程是不存在消息循环(message loop)的,须要调用Looper.prepare()来给线程创建一个消息循环,调用Looper.loop()来使消息循环起作用。从消息队列里取消息。处理消息。
    注:写在Looper.loop()之后的代码不会被马上执行。当调用后mHandler.getLooper().quit()后。loop才会中止,其后的代码才干得以执行。

    Looper对象通过MessageQueue来存放消息和事件。一个线程仅仅能有一个Looper。相应一个MessageQueue。


    下面是Android API中的一个典型的Looper thread实现:

    //Handler不带參数的默认构造函数:new Handler()。实际上是通过Looper.myLooper()来获取当前线程中的消息循环,
    //而默认情况下。线程是没有消息循环的,所以要调用 Looper.prepare()来给线程创建消息循环,然后再通过。Looper.loop()来使消息循环起作用。
    [java] view plaincopy
    1. class LooperThread extends Thread  
    2. {  
    3. public Handler mHandler;  
    4. public void run()   
    5. {  
    6. Looper.prepare();  
    7. mHandler = new Handler()   
    8. {  
    9. public void handleMessage(Message msg)   
    10. {  
    11. // process incoming messages here  
    12. }  
    13. };  
    14. Looper.loop();  
    15. }  

    另,Activity的MainUI线程默认是有消息队列的。

    所以在Activity中新建Handler时,不须要先调用Looper.prepare()。


    那么遇到了有多Low的问题呢:

    项目中重写了一个HandlerThread,然后定义了post方法。然后在主线程中例如以下实现:

            AsyncHandler.post(new Runnable() {
                @Override
                public void run() {
                    try {
                        Looper.prepare();

       // 一坨要异步运行的代码******

                        Looper.loop();
                    } catch (Exception e) {
                        // TODO: handle exception
                    e.printStackTrace();
                    }

    那么明眼人一看就看出问题来了 ,这代码一跑异步代码肯定运行不到啊。为啥呢。且看下prepare的实现:



         /** Initialize the current thread as a looper.
          * This gives you a chance to create handlers that then reference
          * this looper, before actually starting the loop. Be sure to call
          * {@link #loop()} after calling this method, and end it by calling
          * {@link #quit()}.
          */
        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");
            }
            sThreadLocal.set(new Looper(quitAllowed));
        }

    So,简单,却是问题~

  • 相关阅读:
    Python3之random模块常用方法
    Go语言学习笔记(九)之数组
    Go语言学习笔记之简单的几个排序
    Go语言学习笔记(八)
    Python3之logging模块
    Go语言学习笔记(六)
    123. Best Time to Buy and Sell Stock III(js)
    122. Best Time to Buy and Sell Stock II(js)
    121. Best Time to Buy and Sell Stock(js)
    120. Triangle(js)
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7216407.html
Copyright © 2011-2022 走看看