优化项目过程中发现了一个非常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
plain
copy

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

Android 线程 Looper.prepare()、Looper.loop() 使用的更多相关文章

  1. 在子线程中new Handler报错--Can't create handler inside thread that has not called Looper.prepare()

    在子线程中new一个Handler为什么会报以下错误? java.lang.RuntimeException:  Can't create handler inside thread that has ...

  2. 【转】在子线程中new Handler报错--Can't create handler inside thread that has not called Looper.prepare()

    在子线程中new一个Handler为什么会报以下错误? java.lang.RuntimeException:  Can't create handler inside thread that has ...

  3. 转 在子线程中new Handler报错--Can't create handler inside thread that has not called Looper.prepare()

    在子线程中new一个Handler为什么会报以下错误? java.lang.RuntimeException:  Can't create handler inside thread that has ...

  4. Android消息队列和Looper

    1. 什么是消息队列 消息队列在android中对应MessageQueue这个类,顾名思义,消息队列中存放了大量的消息(Message) 2.什么是消息 消息(Message)代表一个行为(what ...

  5. Android消息机制:Looper,MessageQueue,Message与handler

    Android消息机制好多人都讲过,但是自己去翻源码的时候才能明白. 今天试着讲一下,因为目标是讲清楚整体逻辑,所以不追究细节. Message是消息机制的核心,所以从Message讲起. 1.Mes ...

  6. Android -- Looper.prepare()和Looper.loop() —深入版

    Android中的Looper类,是用来封装消息循环和消息队列的一个类,用于在android线程中进行消息处理.handler其实可以看做是一个工具类,用来向消息队列中插入消息的. (1) Loope ...

  7. 【转】Android -- Looper.prepare()和Looper.loop()

    Looper.prepare()和Looper.loop() 原文地址:http://blog.csdn.net/heng615975867/article/details/9194219 Andro ...

  8. Android -- Looper.prepare()和Looper.loop() —深度版

    Android中的Looper类,是用来封装消息循环和消息队列的一个类,用于在android线程中进行消息处理.handler事实上能够看做是一个工具类.用来向消息队列中插入消息的. (1) Loop ...

  9. Android进阶(十六)子线程调用Toast报Can't create handler inside thread that has not called Looper.prepare() 错误

    原子线程调用Toast报Can't create handler inside thread that has not called Looper.prepare() 错误 今天用子线程调Toast报 ...

随机推荐

  1. Js控制样式的诸多方法

    function TableCss(options){ //如果没参数,就退出 if(arguments.length < 1 || !document.getElementById(optio ...

  2. 使用less时的calc()函数问题

    在使用less时写 width:calc(100%-30px); 但在浏览器检查元素的时候总会显示width:70%; 可以在Less中把calc的写法改写成下面这样: width : calc(~& ...

  3. css3通过scale()实现放大功能、通过rotate()实现旋转功能

    css3通过scale()实现放大功能.通过rotate()实现旋转功能,下面有个示例,大家可以参考下 通过scale()实现放大功能 通过rotate()实现旋转功能 而transition则可设置 ...

  4. 解决:efi usb device has been blocked by the current security policy

    解决:efi usb device has been blocked by the current security policy 问题描述:U盘装系统或者其他操作时,是因为BIOS安全策略,出现上述 ...

  5. csf 课件转化为wmv正常格式

    1. 下载csf文件到本地:如下图 2.从下面百度网盘下载到本地: https://pan.baidu.com/s/1BBbgq  n85a 3.安装并出现下面图标,点击打开 4. 运行如下图 5.  ...

  6. Objective-C在ARC下结合GCD的单例模式和宏模版

    单例模式在iOS开发过程中经常用到,苹果提供过objective c单例的比较官方的写法: static MyGizmoClass *sharedGizmoManager = nil; + (MyGi ...

  7. C# 调用指定打印机 (并不是默认)

    this.printDocument1.PrinterSettings.PrinterName = "Microsoft XPS Document Writer"; this.pr ...

  8. 名词解释http隧道、https、SSL层、http代理、在线代理、socks代理区别

    以前听到这几个名词时,总是搞混淆,今天花点时间来记录这几个名词的大概区别,方便以后自己查看. http隧道与https http隧道:“HTTP隧道技术”就是把所有要传送的数据全部封装到HTTP协议里 ...

  9. Python 不定长参数、全局变量、局部变量 day4

    一.不定长参数 在函数定义中,经常会碰到*args 和**kwargs作为参数. 事实上在函数中,*和**才是必要的,args和kwargs可以用其他名称代替 *args 是指不定数量的非键值对参数. ...

  10. MySql 日志查看与设置

    错误日志log-errol 开启方式:在my.ini的[mysqld]选项下:添加代码:log-error=E:\log-error.txt 记录内容:主要是记录启动.运行或停止mysqld时出现的致 ...