[原创]Looper.parpare和Looper.loop()轻松玩转、子线程handler简单代码就可以理解。

本文主要是介绍[原创]Looper.parpare和Looper.loop()轻松玩转、子线程handler简单代码就可以理解。,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前不久测试新版本内存泄露框架的时候,突然想虐一下自己,就写了个内存泄露的代码,并且还想让他泄露的时候不断弹出消息,但是不借助其他线程handler来实现,所以无聊写了个代码,发现验证是正确的,就把代码贴出来,给新手看看,也顺便把为什么可以这样做的原因发到这里。

问题列表

1、为什么主线程死循环而不卡死。
2、handler创建,子线程、使用

3、handler可以创建几个,Looper可以用几个。
4、handler的消息机制原理
5、子线程 弹出toast
6、looper.loop()阻塞了,那么之后的方法怎么才能实现调用, 那么让你在子线程搭建消息通讯你应该怎么搭建

回答

1、之所以不卡死,是因为它一直在处理消息,当没有消息的时候会进行等待,另外它也可以被其他线程唤醒。所以不会造成什么问题。
2、子线程先Looper.parpare() 实例化一个,一个线程只能有一个,
然后就可以创建了,发送的消息并不会被处理,需要开启looper.loop()
才能被处理。
3、handler可以创建多个,但是里面的looper一个线程只能拥有一个,looper只能创建一个,一般情况下不会把他给Loop.quit()的,因为无法再调用了。
4、原理就是hanlder发送的消息加入到消息队列,这个消息队列是threadlocal里面的,这个对象也是本身限制一个线程只能拥有一个,而Looper也是如此,加入的消息将会被Looper.looper()的死循环里面进行处理。
5、在handler.里面的run消息里面可以调用Loop.myLoopre().quit)来实现退出,这样就可以让looper()跳出阻塞。
主线程在应用启动的时候就开启looper了,是无法再prepare了,
子线程无法使用handler 是因为它是从自己线程取looper的,因此可以在子线程Looper.prepare一个,怎么搭建看下面的代码。

说明

网上很流行的文章就是子线程弹出toast的方法代码,但是没有下文,就是坑人的。

Loop.prepare()
Toast.makeText(activity.getApplication(),"" + Thread.currentThread()..getName()+ "线程的toast", Toast.LENGTH_SHORT).show();}
Loop.loop();

但是这样做了之后你怎么处理后面的逻辑?所以这是坑爹的,正确的方法是在loop()之前构建一个带线程延迟的死循环或者再开一个线程然后用这个线程的handler发送消息来实现处理。
下面的代码完美的演示了两种,让toast反复弹出来,而且这个代码是测试内存泄露的,你actiivty执行之后退出,它一直能反复弹出,直到弹出指定时间耗时才退出。

验证

下面代码演示的是

*** 模拟泄漏并且弹出toast* @param activity*/public static void testLeak(Activity activity) {if (!BuildConfig.DEBUG) {return;}Thread thread = new Thread(new Runnable() {@Overridepublic void run() {Activity activity1 = activity;Looper.prepare();Handler handler = new Handler();while (true) {try {Log.w(TAG, "继续持有对象" + activity+Thread.currentThread().getName());Thread.sleep(1000);handler.postDelayed(new Runnable() {int showCount = 0;@Override //反复发消息,这里就是永远死不掉的逻辑,public void run() {Toast.makeText(activity.getApplication(), activity.isDestroyed() + " isdestory? "+Thread.currentThread().getName(), Toast.LENGTH_SHORT).show();handler.postDelayed(this, 4000);//如果loop退出了,这里也不会再执行了if (showCount > 10) {Looper.myLooper().quit();//死掉吧。。}showCount++;}}, 2000);Looper looper = Looper.myLooper();new Thread("子子线程") {@Overridepublic void run() {String name = Thread.currentThread().getName();handler.post(new Runnable() {@Overridepublic void run() {//这类似在子线程中调用主线程的handler.post一样的道理,只不过这里是用的子线程的handler.来玩toast. 子线程本身已经looper.perpare了可以直接toast,但是现在和线程不行只能用叫做'子线程'的的handler进行使用Toast.makeText(activity.getApplication(),"我是再" + name + "线程的toast", Toast.LENGTH_SHORT).show();}});if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {Log.w(TAG, "loop quee count:" + looper.getThread().getName() + "" + ",是否当前线程:" + looper.isCurrentThread());}}}.start();Looper.loop();//这句话会阻塞了 主线程为什么死循环不会阻塞你就懂了,因为一直在handler里面循环,而且还有其他现成可以用主线程的handler给主线程发消息, 自身也一样可以。Log.w(TAG, "终于退出了");break;//loop已死,(阻塞)死循环下去没有意义了,looper.pare只能调用一次,除非反射清空死掉的looper// 。} catch (InterruptedException e) {e.printStackTrace();}}}});thread.setName("子线程");thread.start();}

这篇关于[原创]Looper.parpare和Looper.loop()轻松玩转、子线程handler简单代码就可以理解。的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/959025

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java中如何正确的停掉线程

《Java中如何正确的停掉线程》Java通过interrupt()通知线程停止而非强制,确保线程自主处理中断,避免数据损坏,线程池的shutdown()等待任务完成,shutdownNow()强制中断... 目录为什么不强制停止为什么 Java 不提供强制停止线程的能力呢?如何用interrupt停止线程s

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

使用Spring Cache本地缓存示例代码

《使用SpringCache本地缓存示例代码》缓存是提高应用程序性能的重要手段,通过将频繁访问的数据存储在内存中,可以减少数据库访问次数,从而加速数据读取,:本文主要介绍使用SpringCac... 目录一、Spring Cache简介核心特点:二、基础配置1. 添加依赖2. 启用缓存3. 缓存配置方案方案

python 线程池顺序执行的方法实现

《python线程池顺序执行的方法实现》在Python中,线程池默认是并发执行任务的,但若需要实现任务的顺序执行,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录方案一:强制单线程(伪顺序执行)方案二:按提交顺序获取结果方案三:任务间依赖控制方案四:队列顺序消