优化项目过程中发现了一个非常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. Ajax应用查询员工信息

    首先要用上一篇的步骤启动服务器,建立站点.然后在该站点下创建php文件和html文件. php代码如下,文件名为server.php <?php //设置页面内容是html编码格式是utf-8 ...

  2. FFmpeg编译Android版本

    FFmpeg是很好用的一个音视频库,功能强大,但是用起来并不是很方便.之前一直不想用FFmpeg,因为感觉编译太麻烦,但是到了不得不用的时候了,没办法,参考了网上大神的方法,在这里自己也记录一下方便以 ...

  3. [Android]异常6-TextView setText延迟显示

    背景:Thread和Handler显示数据到界面 解决办法有: 解决一>界面使用了ListView.GridView等,把高度和宽度调整为固定值或者match_parent 解决二>某处U ...

  4. ibatis知识点

    1:ibatis是apache的一个开源的项目,是一个O/R mapping解决方案,优点,小巧,灵活.2:搭建环境:导入ibatis相关jar包,jdbc驱动包等3:配置文件: jdbc连接的属性文 ...

  5. js技巧(二)

    1.封装获取id: function show(Id){ var aa=document.getElementById(Id); return aa; } 调用:console.log(show(&q ...

  6. RabbitMQ 创建用户和创建Virtual host

    https://www.bilibili.com/video/av18997807/?p=3 Virtual host 就是类似数据库吧.

  7. CSS——规避脱标流和vertical-align

    规避脱标流: 1.尽量使用标准流. 2.标准流解决不了的使用浮动. 3.浮动解决不了的使用定位. 问题解决:嵌套盒子在不使用定位的情况下定位到右上角 <!DOCTYPE html> < ...

  8. Centos 安装 Moosefs文件系统

    一.环境介绍Moosefs master:192.168.55.148Moosefs Metalogger:192.168.55.149Moosefs Chunk-01:192.168.55.150M ...

  9. models中,对于(Small)IntegerField类型字段的choices参数在前端的展示

    # models.py class UserInfo(models.Model): gender_choices = ( (1, "男"), (2, "女"), ...

  10. C#学习笔记_12_枚举&结构体

    12_枚举&结构体 枚举 是一种数据类型 适用于某些取值范围有限的数据 语法: [访问权限修饰符] enum 枚举名 { 枚举值 } 枚举名遵循大驼峰命名法 枚举一般情况下是和switch c ...