首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

深入探讨Android异步精髓Handler

这句话的意思是:如果在线程内创建handler必须调用Looper.prepare()。...这是因为UI线程是主线程,系统会自动调用Looper.prepareMainLooper()方法创建主线程的Looper和消息队列MessageQueue Message的发送和处理过程 在讨论完Looper...这里写图片描述 我们在开发中可能会做如上的操作:在主线程中创建Handler,然后在子线程里利用handler.post(Runnable runnable)执行某些操作甚至是耗时的操作。...在该示例中handler是在主线程中创建的,所以它当然会在主线程中处理消息;如此以来该Runnable亦会在主线程中执行;所以,在Runnable的run()方法中执行耗时的操作是不可取的容易导致应用程序无响应...由于垃圾回收器是一个优先级较低的线程,所以不一定会很快发现那些只具有弱引用的对象。为了防止内存溢出,在处理一些占用内存大而且生命周期较长的对象时候,可以尽量使用软引用和弱引用.

57720
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    面试官还问Handler?那我要给你讲个故事

    那子线程怎么创建Handler呢?只需在new Handler()之前调用下Looper.prepare()即可。 2. 为什么主线程可以直接new Handler?...Looper.prepareMainLooper(); ... } //看到这一下就明白了,原来主线程在启动的时候默认就调用了prepareMainLooper(),而在这个方法中调用了...大致意思就说 “由于这个处理程序被声明为一个内部类,它可以防止外部类被垃圾回收。如果处理程序正在对主线程以外的线程使用Looper或MessageQueue,则不存在问题。...如果处理程序正在使用主线程的Looper或MessageQueue,则需要修复处理程序声明,如下所示:将处理程序声明为静态类;并且通过WeakReference引用外部类”。...其实我们写的非静态内部类和非静态匿名内部类,在编译器编译过程中,隐式帮我们传入了this这个参数,这也是为什么,我们平时在方法中能使用this这个关键字的原因,了解了隐式引用,那么为什么它会是导致内存泄漏

    44360

    Android异步消息处理机制完全解析,带你从源码的角度彻底理解

    确实,不过即使只是简单new一下,还是有不少地方需要注意的,我们尝试在程序中创建两个Handler对象,一个在主线程中创建,一个在子线程中创建,代码如下所示: public class MainActivity...,你会发现,在子线程中创建的Handler是会导致程序崩溃的,提示的错误信息为 Can't create handler inside thread that has not called Looper.prepare...说是不能在没有调用Looper.prepare() 的线程中创建Handler,那我们尝试在子线程中先调用一下Looper.prepare()呢,代码如下所示: new Thread(new Runnable...这样基本就将Handler的创建过程完全搞明白了,总结一下就是在主线程中可以直接创建Handler对象,而在子线程中需要先调用Looper.prepare()才能创建Handler对象。...这是由于Handler总是依附于创建时所在的线程,比如我们的Handler是在主线程中创建的,而在子线程中又无法直接对UI进行操作,于是我们就通过一系列的发送消息、入队、出队等环节,最后调用到了Handler

    79660

    Android :安卓学习笔记之 Handler机制 的简单理解和使用

    3、作用和意义 在多线程的应用场景中,将工作线程中需更新UI的操作信息 传递到 UI主线程,从而实现 工作线程对UI的更新处理,最终实现异步消息的处理 多个线程并发更新UI的同时 保证线程安全 4、主要参数...// 即 :若线程中无创建Looper对象,则也无法创建Handler对象 // 故 若需在子线程中创建Handler对象,则需先创建Looper对象...(UI线程) 创建1个循环器对象(Looper),同时也生成了1个消息队列对象(MessageQueue) * 注:该方法在主线程(UI线程)创建时自动调用,即 主线程的Looper对象自动生成,不需手动生成...()方法 = 应用程序的入口 // main()内则会调用Looper.prepareMainLooper()为主线程生成1个Looper对象 /** * 源码分析...()创建 在子线程若不手动创建Looper对象 则无法生成Handler对象 2、根据Handler的作用(在主线程更新UI),故Handler实例的创建场景 主要在主线程 3、生成Looper &

    96710

    java.lang.RuntimeException: Only one Looper may be created per thread解决方法

    题外话 各位友友们,每次出异常之后不要直接问同事直接去百度,要养成一个良好的习惯,先去自己分析,出这个异常的原因是什么,对照着代码,看打印的日志也好debug一步一步走也好,找到出异常的代码块,分析为什么会出异常...首先查看报错信息 Only one Looper may be created per thread:每个线程只能创建一个Looper TTToast.java:10:错误发生在TTToast.java...的第10行,咱们点过去查看 方法解释: Looper.prepare():为当前线程提供一个Looper的实例 TToast.show(context, msg):展示消息 Looper.loop...():在线程中执行消息队列,让 Looper 开始工作,从消息队列里取消息,处理消息 分析 每个线程只能创建一个Looper,说明其他地方已经调用了show这个方法,在线程中已经创建了Looper...,不能再执行Looper.prepare()这个方法了 解决方法 判断当前线程是否创建了Looper,如果未创建则执行Looper.prepare() 如果已创建,直接执行后续操作即可

    1.1K10

    光速2分钟,精通HandlerThread,你还在等什么?

    在Android开发中,HandlerThread是Thread的一个特殊子类,它结合了线程和消息处理机制,使得在一个单独的线程中执行任务变得更加简便。...() // 启动消息循环 Looper.loop() } } 在run()方法中,首先调用Looper.prepare()方法来初始化Looper。...Looper.prepare()方法会创建一个Looper对象,并将其绑定到当前线程。 然后,调用Looper.loop()方法来启动消息循环。...通过HandlerThread的Looper创建Handler。 使用Handler发送消息。 在HandlerThread的Looper中处理消息。...处理异常: 在HandlerThread的任务中,适当地处理异常,避免因未捕获的异常导致线程崩溃。 线程安全: HandlerThread是线程安全的,但是Handler不一定是线程安全的。

    22710

    Android异步通信:深入剖析Handler机制源码

    Handler 机制简介 定义 一套 Android 消息传递机制 作用 在多线程的应用场景中,将工作线程中需更新UI的操作信息 传递到 UI主线程,从而实现 工作线程对UI的更新处理,最终实现异步消息的处理...// 即 :若线程中无创建Looper对象,则也无法创建Handler对象 // 故 若需在子线程中创建Handler对象,则需先创建Looper对象...(UI线程) 创建1个循环器对象(Looper),同时也生成了1个消息队列对象(MessageQueue) * 注:该方法在主线程(UI线程)创建时自动调用,即 主线程的Looper对象自动生成,不需手动生成...= 应用程序的入口 // main()内则会调用Looper.prepareMainLooper()为主线程生成1个Looper对象 /** * 源码分析:main()...()创建 在子线程若不手动创建Looper对象 则无法生成Handler对象 根据Handler的作用(在主线程更新UI),故Handler实例的创建场景 主要在主线程 生成Looper & MessageQueue

    66720

    Android Handler异步通信:深入详解Handler机制源码

    Handler 机制简介 定义 一套 Android 消息传递机制 作用 在多线程的应用场景中,将工作线程中需更新UI的操作信息 传递到 UI主线程,从而实现 工作线程对UI的更新处理,最终实现异步消息的处理...// 即 :若线程中无创建Looper对象,则也无法创建Handler对象 // 故 若需在子线程中创建Handler对象,则需先创建Looper对象...(UI线程) 创建1个循环器对象(Looper),同时也生成了1个消息队列对象(MessageQueue) * 注:该方法在主线程(UI线程)创建时自动调用,即 主线程的Looper对象自动生成,不需手动生成...()方法 = 应用程序的入口 // main()内则会调用Looper.prepareMainLooper()为主线程生成1个Looper对象 /** * 源码分析...()创建 在子线程若不手动创建Looper对象 则无法生成Handler对象 根据Handler的作用(在主线程更新UI),故Handler实例的创建场景 主要在主线程 生成Looper & MessageQueue

    1.2K20

    笔记——安卓消息机制Handler(十六)

    Looper.prepare()->new Handler()-> sendMessage()->MessageQueue->Looper.loop()->handlerMessage(),但是在UI线程是主线程中...,系统会自动调用Looper.prepareMainLooper()方法创建主线程的Looper(Looper.prepare()与Looper.loop())和消息队列MessageQueue。...在prepare()内会调用sThreadLocal.set(new Looper(quitAllowed)),至于Looper,它在Android的消息机制中担负着消息轮询的角色,它会不间断地查看MessageQueue...中是否有新的未处理的消息;若有则立刻处理,若无则进入阻塞。...Handler创建的时候会采用当前线程的Looper来构造消息循环系统,而ThreadLocal可以在不同的线程中互不干扰地存储并提供数据,通过ThreadLocal可以轻松获取每个线程的Looper。

    53640

    笔记——Android零碎知识摘录(一)

    虽然说加了这个属性,能使其他的程序不能调用。但是,需要注意的是,如果两个程序的userid是一样的话,exported=”false“就没有用了。...指在同一时刻,有多条指令在多个处理器上同时执行。 并发的多个任务之间是互相抢占资源的->单cpu 并行的多个任务之间是不互相抢占资源的->多cpu 只有在多CPU的情况中,才会发生并行。...Looper.prepare()->new Handler()->sendMessage()->MessageQueue->Looper.loop()->handlerMessage(),但是在UI线程是主线程中...,系统会自动调用Looper.prepareMainLooper()方法创建主线程的Looper(Looper.prepare()与Looper.loop())和消息队列MessageQueue。...在prepare()内会调用sThreadLocal.set(new Looper(quitAllowed)),至于Looper,它在Android的消息机制中担负着消息轮询的职责,它会不间断地查看MessageQueue

    40420

    【Android】Handler 机制 ( Handler | Message | Looper | MessageQueue )

    Handler 创建 : 这里注意 只能在 Looper 线程中创建 Handler , 普通线程不能创建 Handler ; ① 主线程 : 主线程中可以直接创建 Handler , 因为在点击应用图标后就会...() 方法 , 将线程转为 Looper 线程 , 因为 创建 Handler 时 , 会关联线程的 Looper 对象 , 普通的子线程是没有 Looper 对象的 , 调用 Looper.prepare...Looper 线程就是在普通线程的基础是哪个 , 加入了 Looper 用于消息调度 , 然后将消息转发给 Handler 进行处理 , 这样就实现了 在其它线程中 , 将任务异步分配给该 Looper...Looper.prepare() 静态方法 , 该方法的作用是创建 Looper 变量 , 存储在了 ThreadLocal 中 , 将当前普通线程转为 Looper 线程 ; ③ 实例化 Handler...成员 : 一定要在 Looper.prepare() 之后实例化成员 , 因为如果在之前实例化 , Handler 与 Looper 无法产生关联 ; ④ 轮询消息队列 : 调用 Looper.loop

    1.4K20

    Android 源码分析 —— Handler、Looper 和 MessageQueue

    在调用 Handler 的 postXXX 和 sendXXX 时,可以指定当队列准备好时立即处理它们,也可以指定延时一段时间后处理,或某个绝对时间点处理。...为应用程序创建一个进程时,其主线程专用于运行消息队列,该消息队列负责管理顶层应用程序对象(activities,broadcast receivers 等)以及它们创建的窗口。...关联的消息队列中,并适时进行处理。...Looper 用于为线程执行消息循环的类。线程默认没有关联的消息循环,如果要创建一个,可以在执行消息循环的线程里面调用 prepare() 方法,然后调用 loop() 处理消息,直到循环停止。...上文提到,应用程序的主线程是运行一个消息循环,在代码里是如何反映的?

    64620

    通信之线程间通信(上)-handler

    本文主要有三大方面 一是handler,Looper,messagequeue之间概念 二是线程间通信时handler的使用,包括在主线程中创建handler和在子线程中创建handler 三是对于looper...对象发送给消息队列入列,二是消息队列对消息的处理又是在handler中)每一个handler和一个单一线程以及一个该线程的消息队列对应。...对于handler有两种用法:在未来的某一刻去执行一个message或者是runnable.或者是在另一个线程中执行一个action(即在该线程中使用另一个线程中的handler处理消息) 可以通过post...当你的应用程序正在进行处理消息的操作时,应用程序主线程会专门用来运行一个消息队列来管理顶级的应用程序对象(activities,broadcastreceivers,等等)以及任何他们创建的窗口。...三:Looper: Looper用来为一个线程循环消息message.线程默认是没有消息循环的;可以调用Looper.prepare()方法创建一个message loop,在loop停止之前可以用它来处理

    55410

    Android 源码分析 —— Handler、Looper 和 MessageQueue

    在调用 Handler 的 postXXX 和 sendXXX 时,可以指定当队列准备好时立即处理它们,也可以指定延时一段时间后处理,或某个绝对时间点处理。...为应用程序创建一个进程时,其主线程专用于运行消息队列,该消息队列负责管理顶层应用程序对象(activities,broadcast receivers 等)以及它们创建的窗口。...关联的消息队列中,并适时进行处理。...Looper 用于为线程执行消息循环的类。线程默认没有关联的消息循环,如果要创建一个,可以在执行消息循环的线程里面调用 prepare() 方法,然后调用 loop() 处理消息,直到循环停止。...上文提到,应用程序的主线程是运行一个消息循环,在代码里是如何反映的?

    40420

    Handler消息传递机制

    上面的Handler是在主线程中创建的,当我们在子线程创建一个Handler时,运行程序会报错: java.lang.RuntimeException: Can't create handler inside...一个线程默认是没有消息循环的,如果要创建一个,需要在线程先调用Looper.prepare,然后调用Looper.loop使其处理消息,知道循环结束。 基本上是和Handler交互处理消息循环。...回到最开始的例子,Handler的使用步骤如下: 在线程A内创建Handler,重载handleMessage方法处理消息 在线程B使用Handler.sendMessage等发送消息 消息从线程B发到线程...线程创建uiHandler,此时这个Handler属于UIThread,其内部Looper也是UIThread创建的,MQ也在UIThread(Looper内持有)。...如果在子线程中想更新UI线程,除了在UI线程创建Handler外,也可以在子线程创建Handler,不过需要给这个Handler指定主线程的Looper: Handler mainHandler = new

    2.4K20

    详解 Android 中的 HandlerThread

    HandlerThread是Android API提供的一个便捷的类,使用它我们可以快速的创建一个带有Looper的线程,有了Looper这个线程,我们又可以生成Handler,那么HandlerThread...实现原理 在介绍原理之前,我们先使用普通的Thread来创建一个Handler,创建的过程大致如下: 1 2 3 4 5 6 7 8 9 10 11 12 Handler mHandler; private...mHandler = new Handler(Looper.myLooper()); Looper.loop(); } }.start(); } 实现很简单,在目标线程内如下配置...调用Looper.prepare 创建与当前线程绑定的Looper实例 使用上面创建的Looper生成Handler实例 调用Looper.loop()实现消息循环 明白上面的实现步骤,HandlerThread...以上的这些优先级都是可以在程序中设置的,除此之外还有不可控的优先级均有系统进行自动调整。

    75950
    领券