当前位置:首页 » 安卓系统 » android死循环

android死循环

发布时间: 2023-01-30 10:27:43

1. Android-Looper

Looper.loop是一个死循环,拿不到需要处理的Message就会阻塞,那在UI线程中为什么不会导致ANR?

首先我们来看造成ANR的原因:
1.当前的事件没有机会得到处理(即主线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了)
2.当前的事件正在处理,但没有及时完成

我们再来看一下APP的入口ActivityThread的main方法:

显而易见的,如果main方法中没有looper进行死循环,那么主线程一运行完毕就会退出,会导致直接崩溃,还玩什么!

现在我们知道了消息循环的必要性,那为什么这个死循环不会造成ANR异常呢?

我们知道Android 的是由事件驱动的,looper.loop() 不断地接收事件、处理事件,每一个点击触摸或者说Activity的生命周期都是运行在 Looper的控制之下,如果它停止了,应用也就停止了。只能是某一个消息或者说对消息的处理阻塞了 Looper.loop(),而不是 Looper.loop() 阻塞它,这也就是我们为什么不能在UI线程中处理耗时操作的原因。
主线程Looper从消息队列读取消息,当读完所有消息时,主线程阻塞。子线程往消息队列发送消息,唤醒主线程,主线程被唤醒只是为了读取消息,当消息读取完毕,再次睡眠。因此loop的循环并不会对CPU性能有过多的消耗。

初始化当前线程和Looper,这样可以在实际开始启动循环(loop())之前创建一个Handler并且关联一个looper。确保在先调用这个方法,然后调用loop()方法,并且通过调用quit()结束。

这里面的入参boolean表示Looper是否允许退出,true就表示允许退出,对于false则表示Looper不允许退出。

初始化当前当前线程的looper。并且标记为一个程序的主Looper。由Android环境来创建应用程序的主Looper。因此这个方法不能由咱们来调用。另请参阅prepare()

这里的sThreadLocal.get()是和prepare(boolean)方法里面的sThreadLocal.set(new Looper(quitAllowed));一一对应的。而在prepareMainLooper()方法里面。

退出循环
将终止(loop()方法)而不处理消息队列中的任何更多消息。在调用quit()后,任何尝试去发送消息都是失败的。例如Handler.sendMessage(Message)方法将返回false。因为循环终止之后一些message可能会被无法传递,所以这个方法是不安全的。可以考虑使用quitSafely()方法来确保所有的工作有序地完成。

安全退出循环
调用quitSafely()方法会使循环结束,只要消息队列中已经被传递的所有消息都将被处理。然而,在循环结束之前,将来不会提交处理延迟消息。
调用退出后,所有尝试去发送消息都将失败。就像调用Handler.sendMessage(Message)将返回false。

2. 用eclipse做android,每次运行的时候都是这个错,而且还死循环,帮我解决一下啊

你的原因是:主板的BLOS信息因为一些软件安装处于不确定状态,开机的时候选择F1键会进入蓝屏状态的华硕blos设置界面,其实里面的参数不需要修改,只需要按一下,F10键(F10是保存BLOS的设置信息)然后它会提示你是否保存,选择YES。就可以了,以后开机就不会出现这个问题了。祝楼主好运。

3. 安卓按键精灵死循环如何解救

先看一下"行数"是多少,是不是有空白行没有算进去

4. android从写onDraw为什么进入了死循环

this.postInvalidate();
这条语句的含义是在子线程中通知UI线程强制更新,而你的类是View类型,其更新的含义就是重绘这个界面,也就是说不停的调用了onDraw()这个方法绘制界面。

所以我建议朋友你梳理下业务逻辑,加入判断进行控制。

望采纳,谢谢~~

5. android后退键进入死循环,第一个页面后退到第二个,第二个后退又到第一个.求教,谢谢

看了你下面的代码、目测你这个问题应该不是经常出现、之所以会出现 应该是你退出程序的时候只关闭了第一个activity、 第二个 activity、
还是打开的,那么你多次重复进入 就会有多个第二个页面、可能你第二个页面又有跳转到第一个页面的代码这就导致了第一个页面每次都关闭 第二个页面关闭不了,病跳转到第一个页面 第一个又关闭。。。。 死循环了,解决这个问题你可以在第二个页面加入xxxxactivity。this,finish(); OK 应该就是这样

6. android 子线程中的死循环怎么设置

设置标记变量,while(isValid){}
如果想退出的时候,将isValid置为false

7. Android中为什么主线程不会因为Looper.loop里的死循环卡死

Handler类怎么会算线程呢,它是用来发送和处理消息用的,而Looper类是用来存储消息队列以及处理消息循环的一个封装类。 UI线程本身已经实现了消息队列,所有可以直接创建Handler类 而自己创建的线程要实现消息处理,必须调用Looper.prepare()来创建消息队列以及其他一些步骤的初始化,再创建Handler,最后调用Looper.loop()实现消息循环

8. android程序锁问题(程序锁进入死循环)

没看懂。。。

9. Android-保活

Low Memory Killer

打开的应用越多,后台缓存的进程也越多。因为系统出于体验和性能上的考虑,app在退到后台时系统并不会真正的kill掉这个进程,而是将其缓存起来。于是在系统内存不足的情况下,系统开始依据自身的一套进程回收机制来判断要kill掉哪些进程,以腾出内存来供给需要的app, 这套杀进程回收内存的机制就叫 Low Memory Killer。

进程的优先级(by:https://developer.android.google.cn/guide/components/activities/process-lifecycle?hl=zh-cn)

前台进程

用户正在使用的程序,一般系统是不会杀死前台进程的,除非用户强制停止应用或者系统内存不足等极端情况会杀死。

可见进程

用户正在使用,看得到,但是摸不着,没有覆盖到整个屏幕,只有屏幕的一部分可见进程不包含任何前台组件,一般系统也是不会杀死可见进程的,除非要在资源吃紧的情况下,要保持某个或多个前台进程存活施。

服务进程

在内存不足以维持所有前台进程和可见进程同时运行的情况下,服务进程会被杀死。

后台进程

系统可能随时终止它们,回收内存。

空进程

某个进程不包含任何活跃的组件时该进程就会被置为空进程,完全没用,杀了它只有好处没坏处,第一个干它。

内存阈值

内存阈值在不同的手机上不一样,一旦低于该值,Android便会杀死对应优先级的进程。一旦低于该值,Android便开始按逆序关闭进程。即优先级从最高的空进程开始,逆序关闭,直到内存足够。

如何判断进程的优先级?

通过 oom_adj 值,判断进程的优先级,不同手机的oom_adj 值可能不一样。

我们了解这个有什么用呢?PS:了解这个你才能想办法保证自己怎么不被杀掉。

网上的一些方案和自己认为有用的方案

1 开启一个像素Activity(伪前台进程)

在锁屏的时候在本进程开启一个Activity,为了欺骗用户,让这个Activity的大小是1像素,并且透明无切换动画,在开屏幕的时候,把这个Activity关闭掉,所以这个就需要监听系统锁屏广播。

我们的应用就始终和前台进程是一样的优先级了,为了省电,系统检测到锁屏事件后一段时间内会杀死后台进程,如果采取这种方案,就可以避免了这个问题,但是还是有被杀掉的可能。

Android5.0以下:

Process.killProcessQuiet(pid);

Android5.0以后:

Process.killProcessQuiet(app.pid);

Process.killProcessGroup(app.info.uid, app.pid);

应用退出后,ActivityManagerService不仅把主进程给杀死,另外把主进程所属的进程组一并杀死,这样一来,由于子进程和主进程在同一进程组,子进程在做的事情,也就停止了。

2 相互唤醒(广播唤醒)

相互唤醒的意思就是,假如你手机里装了支付宝、淘宝、天猫、UC等阿里系的app,那么你打开任意一个阿里系的app后,有可能就顺便把其他阿里系的app给唤醒了。这个完全有可能的。此外,开机,网络切换、拍照、拍视频时候,利用系统产生的广播也能唤醒app,不过Android N已经将这三种广播取消了。

3 JobSheler机制保活(不推荐)

JobSheler是作为进程死后复活的一种手段,native进程方式最大缺点是费电, Native 进程费电的原因是感知主进程是否存活有两种实现方式,在 Native 进程中通过死循环或定时器,判断主进程是否存活,当主进程不存活时进行拉活。其次5.0以上系统不支持。  但是JobSheler可以替代在Android5.0以上native进程方式,这种方式即使用户强制关闭,部分厂商手机(如:华为)也能被拉起来,但AndroidN失效。

4 粘性服务&与系统服务捆绑()

这个是系统自带的,onStartCommand方法必须具有一个整形的返回值,这个整形的返回值用来告诉系统在服务启动完毕后。Service的onStartCommand方法里返回 STATR_STICK,onDestory中start自启(准确的将算不上进程拉活,只能算service自启,force_stop后不能正常拉活)。

5 监听第三方app开放的静态广播(同2)

需要大量反编译app去找开放的静态广播,而且不保证长期有效,可能第三方开放广播在版本升级时改为私有广播,如果自己公司有多个app,可广播互相拉起。

6 NDK+Socket通过fork实现进程保活方案()

实现进程守护实际是守护app的主要服务,当app主进程被系统kill时,主要服务也会杀死,守护进程将其唤醒。

实现原理图:

进程保活方案调研结果

未能实现真正意义上的进程保活。

光从保活这一点来说,绑定一个像素activity和循环一个无声的声音这种方法比较好,但是对用户来说太流氓了,不推荐。  对于有硬性需求的,可以引导用户加入白名单。至于推送,  可以尝试集成多个推送方案,小米,华为等都有推送sdk,在对应手机上可以确保收到消息,  然后像网络这种是多app公用通道的,也就是手机中有一个使用网络推送的app被允许后台启动,就能让其他app收到推送。随着Android版本的不断更新及国内厂商对ROM的不断优化,如何最大可能的对进程保活,是Android一道需要长期学习/钻研的学问,也是Android开发者不得不面对的问题。

引援:https://www.jianshu.com/p/1c353edf73ba

10. Android Handle中Looper.loop()的死循环为什么在主线程中不会产生卡死现象

1. 主线程,负责一些UI更新操作,归类为一个线程,线程在Android中是有生命周期的,任务最终是会结束的。
2. Looper.loop()的死循环正是维护了主线程的超长生命周期,loop方法一直循环处理任务,没有任务的时候会休眠,有任务的时候会唤醒然后进行处理,所以也不会占用太多系统资源。
3. 卡死,可能有误解,循环的过程中本生不会出现ANR,在循环的过程中,如果执行了耗时且在规定时间内没有完成消息派发,才会出现ANR。

热点内容
内置存储卡可以拆吗 发布:2025-05-18 04:16:35 浏览:336
编译原理课时设置 发布:2025-05-18 04:13:28 浏览:378
linux中进入ip地址服务器 发布:2025-05-18 04:11:21 浏览:612
java用什么软件写 发布:2025-05-18 03:56:19 浏览:32
linux配置vim编译c 发布:2025-05-18 03:55:07 浏览:107
砸百鬼脚本 发布:2025-05-18 03:53:34 浏览:944
安卓手机如何拍视频和苹果一样 发布:2025-05-18 03:40:47 浏览:741
为什么安卓手机连不上苹果7热点 发布:2025-05-18 03:40:13 浏览:803
网卡访问 发布:2025-05-18 03:35:04 浏览:511
接收和发送服务器地址 发布:2025-05-18 03:33:48 浏览:372