[原创]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

相关文章

闲置电脑也能活出第二春?鲁大师AiNAS让你动动手指就能轻松部署

对于大多数人而言,在这个“数据爆炸”的时代或多或少都遇到过存储告急的情况,这使得“存储焦虑”不再是个别现象,而将会是随着软件的不断臃肿而越来越普遍的情况。从不少手机厂商都开始将存储上限提升至1TB可以见得,我们似乎正处在互联网信息飞速增长的阶段,对于存储的需求也将会不断扩大。对于苹果用户而言,这一问题愈发严峻,毕竟512GB和1TB版本的iPhone可不是人人都消费得起的,因此成熟的外置存储方案开

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu2289(简单二分)

虽说是简单二分,但是我还是wa死了  题意:已知圆台的体积,求高度 首先要知道圆台体积怎么求:设上下底的半径分别为r1,r2,高为h,V = PI*(r1*r1+r1*r2+r2*r2)*h/3 然后以h进行二分 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#includ

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

usaco 1.3 Prime Cryptarithm(简单哈希表暴搜剪枝)

思路: 1. 用一个 hash[ ] 数组存放输入的数字,令 hash[ tmp ]=1 。 2. 一个自定义函数 check( ) ,检查各位是否为输入的数字。 3. 暴搜。第一行数从 100到999,第二行数从 10到99。 4. 剪枝。 代码: /*ID: who jayLANG: C++TASK: crypt1*/#include<stdio.h>bool h

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

uva 10387 Billiard(简单几何)

题意是一个球从矩形的中点出发,告诉你小球与矩形两条边的碰撞次数与小球回到原点的时间,求小球出发时的角度和小球的速度。 简单的几何问题,小球每与竖边碰撞一次,向右扩展一个相同的矩形;每与横边碰撞一次,向上扩展一个相同的矩形。 可以发现,扩展矩形的路径和在当前矩形中的每一段路径相同,当小球回到出发点时,一条直线的路径刚好经过最后一个扩展矩形的中心点。 最后扩展的路径和横边竖边恰好组成一个直

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言