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

时间: 2024-08-24 00:14:33

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

android线程消息传递机制——Looper,Handler,Message

android线程消息传递机制——Looper,Handler,Message 在引入这些概念之前,我们先了解一下引入这些机制的背景. 出于性能优化的考虑,Android的UI操作并不是线程安全的(如果你不懂什么是线程安全,可以阅读一下<一起探究多进程与多线程>里的数据安全与可重入),这意味着如果有多个线程同时操作某个UI组件,可能导致线程安全问题.为了解决这个问题,Android制定了一条简单的规则:只允许UI线程修改Activity里的UI组件.这个UI线程也通常被我们称为主线程. 在此引

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

在子线程中new一个Handler为什么会报以下错误? java.lang.RuntimeException:  Can't create handler inside thread that has not called Looper.prepare()  这是因为Handler对象与其调用者在同一线程中,如果在Handler中设置了延时操作,则调用线程也会堵塞.每个Handler对象都会绑定一个Looper对象,每个Looper对象对应一个消息队列(MessageQueue).如果在创建Ha

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

Android消息机制好多人都讲过,但是自己去翻源码的时候才能明白. 今天试着讲一下,因为目标是讲清楚整体逻辑,所以不追究细节. Message是消息机制的核心,所以从Message讲起. 1.Message是什么? 看一个从消息池中取出一个msg的方法: public static Message obtain(Handler h, int what, int arg1, int arg2, Object obj) { Message m = obtain(); m.target = h; m

Android消息队列和Looper

1. 什么是消息队列 消息队列在android中对应MessageQueue这个类,顾名思义,消息队列中存放了大量的消息(Message) 2.什么是消息 消息(Message)代表一个行为(what)或者一串动作(Runnable),有两处会用到Message:Handler和Messenger 3.什么是Handler和Messenger Handler大家都知道,主要用来在线程中发消息通知ui线程更新ui.Messenger可以翻译为信使,可以实现进程间通信(IPC),Messenger采

Android线程与消息机制

# 标签: 读博客 UI线程 先从一个经典错误开始: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views 为什么会出现这个错误? UI的呈现必须在同一个线程里面完成. 试想,如果多个线程可以绘制UI,那么肯定乱套,呈现结果不可预期. 因此界面程序必然有一个UI线程,android,ja

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

Android中的Looper类,是用来封装消息循环和消息队列的一个类,用于在android线程中进行消息处理.handler事实上能够看做是一个工具类,用来向消息队列中插入消息的. (1) Looper类用来为一个线程开启一个消息循环.     默认情况下android中新诞生的线程是没有开启消息循环的.(主线程除外,主线程系统会自己主动为其创建Looper对象,开启消息循环.)     Looper对象通过MessageQueue来存放消息和事件.一个线程仅仅能有一个Looper,相应一个M

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

Looper.prepare()和Looper.loop() 原文地址:http://blog.csdn.net/heng615975867/article/details/9194219 Android中的Looper类,是用来封装消息循环和消息队列的一个类,用于在android线程中进行消息处理.handler其实可以看做是一个工具类,用来向消息队列中插入消息的. (1) Looper类用来为一个线程开启一个消息循环.     默认情况下android中新诞生的线程是没有开启消息循环的.(主

Android中Looper的实现原理,为什么调用Looper.prepare()就在当前线程关联了一个Looper对象,它是如何实现的。

1.线程间通信机制 首先,looper.handler.messagequeue三者共同实现了android系统里线程间通信机制. 如在A.B两个子线程之间需要传递消息,首先给每个子线程绑定一套handler.looper.messagequeue机制,然后这三个对象都与其所属线程对应. 然后A线程通过调用B线程的Handler对象,发送消息.这个消息会被Handler发送到B线程的messagequeue中,而属于B线程的Looper对象一直在for循环里无限遍历MessageQueue, 一

Android 线程更新UI报错 : Can&#39;t create handler inside thread that has not called Looper.prepare()

MainActivity中有一个按钮,绑定了save方法 public void save(View view) { String title = titleText.getText().toString(); String timelength = lengthText.getText().toString(); ExecutorService exec = Executors.newCachedThreadPool(); exec.execute(new NewsService(getApp