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,简单,却是问题~

  • 相关阅读:
    Python之Numpy详细教程
    poj-1151-Atlantis-线段树求面积并
    hdu 5277 YJC counts stars
    webpack安装和配置
    算法——基础篇——高速排序
    nyoj914(二分搜索+贪心)
    Android图片旋转,缩放,位移,倾斜,对称完整演示样例(一)——imageView.setImageMatrix(matrix)和Matrix
    我是怎么利用微信做兼职月入1W的
    对象逆序列化报错:java.lang.ClassNotFoundException
    输入法之核心词典构建
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7216407.html
Copyright © 2011-2022 走看看