前言
最新的建议是:“安卓从进入到放弃都保持活力:引导用户进入白名单(以七种主要型号的白名单为例)”(本文发表于2020年6月13日)。
关于安卓平台的生存过程,这肯定是所有安卓开发者关注的内容之一。当你在网上搜索安卓程序以保持活力时,你会发现各种各样的做法都很棒,其中大多数都非常不可靠。不久前,Github还出现了一个非常流行的“黑色技术”进程保持活力库,声称该进程可以永远存在(参见文章“安卓后台保持活力实践总结:即时消息应用无法治愈的疾病”末尾推荐的开源解决方案)。
我带着学习和崇拜的心情去了基特布,发现很多人提出了这个问题,并说各种各样的机器不可能成功地生存。
看到这一点,我立刻松了一口气。坦率地说,我真的不希望这种黑色技术存在。这只会滋生更多的流氓应用程序,降低我的大型安卓平台的流畅度。
那么,什么样的应用程序需要进程保持活动呢?通常,为了确保消息的实时和全时间传递,即时消息应用程序(包括即时消息聊天应用程序、消息推送服务等)。)必须保持流程或服务的活力。就这个看似无关紧要的问题而言,它实际上已经得到了处理,因为许多安卓手机和安卓系统版本之间的差异使得问题的处理充满了不确定性。
本文将详细介绍关于保持活力的过程的知识,但事先声明以下四点:
本文来源于我开发安卓以来各方的综合数据;
在不节约能源的情况下保持流程运行的方法都是流氓行为;
这篇文章不是教你永生的过程。如果你期望获得永生,请忽略这篇文章;
这篇文章有一些错误,所以请留下评论并互相讨论(请拍拍砖)。
保持活力的方法
目前,行业中的安卓流程保活手段主要分为三种类型:黑色、白色和灰色,一般实现思路如下:
黑保活:不同的应用程序进程通过广播相互唤醒(包括通过系统提供的广播唤醒);
保持活力:启动前台服务;;
灰色保持活动:使用系统漏洞启动前台服务。
黑人保持活力
所谓的黑保活意味着不同的应用程序进程被用来通过广播唤醒彼此。给出三个更常见的场景:
场景1:在启动、切换网络、拍照和拍摄视频时,使用系统生成的广播来唤醒应用程序;;
场景2:访问第三方sdk也会唤醒相应的应用程序流程,例如微信sdk会唤醒微信,支付宝SDK会唤醒支付宝。这种分歧将直接触发接下来的场景3;
场景3:如果你的手机上安装了支付宝、淘宝、天猫、加州大学和其他阿里应用,你可以在打开阿里应用后顺便唤醒其他阿里应用。(以阿里为例,事实上,英美烟草几乎是一样的)。
没错,我们的安卓手机就是由上述场景一步一步给拖卡机的。
鉴于场景1,据估计谷歌已经开始意识到这些问题,所以在最新的安卓系统中,三种类型的广播,如动作_新_图片(拍照)、动作_新_视频(拍照)和连接性_动作(网络切换)都被取消了,这无疑给许多应用带来了沉重的打击。
当你开始广播的时候,我记得一些定制光盘的制造商已经把它移除了。对于场景2和场景3,调用SDK来唤醒应用程序进程是一种正常行为,因此这里不再讨论。
然而,当分析LBE应用程序之间的唤醒路径时,发现了两个问题:
许多推SDKs也有唤醒应用的功能;
应用之间有许多复杂的唤醒路径。
我会给你看我手机的测试结果(我的手机是小米4C,它有原生的安卓5.1系统,并且已经获得了超级用户权限来查看这些唤醒路径)。
15组相互唤醒路径:
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
所有唤醒路径:
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
我们直接点击小书的唤醒路径来查看:
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
您可以看到上面的三条唤醒路径,但是所涵盖的唤醒应用程序总数已经达到23+43+28,这真是令人惊讶。请注意,这只是我手机上一个应用程序的唤醒路径。在这里思考是不是有点可怕?
当然,这里还有一个问题,那就是,我们不知道LBE基于什么样的想法来分析这些唤醒路径和唤醒应用。因此,我们不能确定分析结果是否准确。如果有LBE童鞋谁读了这篇文章,你能告诉我们思路吗?然而,当手机打开一个应用程序时,它会唤醒很多人,但我个人体验到这种酸味......
白人保持活力
白色保活方法非常简单,即调用系统api启动前台服务进程,该进程将在系统的通知栏中生成一个通知,用于让用户知道有这样一个应用程序正在运行,即使当前应用程序退回到后台。喜欢下面的LBE和QQ音乐:
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
格雷活着
灰色保持活力,这是最广泛使用的方法。它使用系统漏洞来启动前台服务进程,这与普通启动方法不同,因为它不会在系统通知栏中显示通知,并且看起来像后台服务进程正在运行。这样做的优点是用户不会注意到您正在运行前台进程(因为您看不到通知),但是您的进程优先级高于普通后台进程。
所以如何利用系统中的漏洞,一般的实现思路和代码如下:
想法1: API < 18,新通知()在前台服务启动时直接传入;
想法2: API >= 18,同时启动两个具有相同id的前台服务,然后停止稍后启动的服务。
01020304050607080910111213141516171819202122232425262728293031323334公共类GrayService扩展服务{私有最终静态int GRAY _ SERVICE _ ID = 1001@覆盖公共int onStartCommand(意图、int标志、int startId) { if(生成。SDK_INT < 18) {开始前景(灰色_服务_标识,新通知());//API < 18,此方法可以有效地隐藏通知上的图标}否则{意图内部意图=新意图(此,grainnerservice . class);开始服务(内部意图);开始前景(灰色_服务_标识,新通知());}返回super.onStartCommand(意图、标志、开始标识);}.../* * *在应用编程接口> = 18 *的平台上使用的灰色保持活动方式/公共静态类灰色服务扩展服务{ @覆盖公共int onStartCommand(意图、int标志、int开始标识){开始前景(GRAY_SERVICE_ID、新通知());停止前景(true);stop self();返回super.onStartCommand(意图、标志、开始标识);} }}
代码大致如下,这可以让您在不知情的情况下启动前台服务。事实上,市场上的许多应用程序都使用这种灰色的保活方法。什么?你不相信?好吧,我们去看看。过程非常简单。打开一个应用程序,查看系统通知栏中是否有通知。否则,我们将进入手机的adb外壳模式,并输入以下外壳命令:
1dumpsys活动服务包名称
用指定的包名打印出所有进程的服务信息,并查看是否有任何关键信息。如果您在通知栏中没有看到属于该应用程序的通知,并且看到isForeground=true,这意味着该应用程序使用了这种灰色保持活动的方法。
以下是我手机上微信、qq、支付宝和Momo的测试结果。如果你感兴趣,你可以自己验证。
微信:
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
手机QQ:
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
支付宝:
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
沫沫:
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
事实上,谷歌意识到了这个漏洞的存在,并一步一步地阻止了它。这就是为什么这种保活模式分为两种情况:API >= 18和API < 18。从Android5.0中ServiceRecord类的postNotification函数的源代码中,您可以看到这样一个注释:
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
当API >= 18方案有一天失败时,我们将不得不另寻出路。应该注意的是,使用灰色保活并不意味着您的服务永远不会死亡,但只能说该流程的优先级提高了。如果你的应用程序进程占用了大量的内存,那么根据循环利用进程的策略,它也会杀死你的应用程序。对灰色保活如何利用系统漏洞而不显示通知感兴趣,您可以研究系统的相关源代码,如服务记录、通知管理服务等。因为这不是本文的重点,所以不会详细描述。
离题
这里,我们基本上介绍了三种实现:黑色、白色和灰色。仅仅从代码层面保持活力是不够的。我希望我们能够通过系统的流程循环机制来理解保活,这样我们就可以更好地避免踩在流程被扼杀的坑上。
了解安卓流程回收机制
熟悉安卓系统的童鞋知道,当应用程序退回到后台时,系统不会真正扼杀这个过程,而是为了体验和性能而缓存它。您打开的应用程序越多,在后台缓存的进程就越多。在系统内存不足的情况下,系统开始根据自己的一套进程回收机制来判断应该杀死哪些进程,从而释放内存来提供所需的应用程序。杀死进程和回收内存的机制称为低内存黑仔,它是基于Linux内核的OOM黑仔(内存不足杀手)机制。
理解低记忆黑仔,然后了解什么是低记忆?它是由linux内核分配给每个系统进程的一个值,代表进程的优先级。流程回收机制根据此优先级决定是否回收。对于oom_adj的角色,您只需要记住以下几点:
一个过程的oom_adj越大,这个过程的优先级越低,就越容易被终止和回收。规模越小,流程的优先级越高,就越不可能被杀死和回收
普通应用程序进程的Oom_adj > = 0,系统进程的oom _ adj是可能的
那么我们如何看待这个过程的可调价值呢?我们需要使用以下两个shell命令:
1ps | grep PackageName //获取您指定的流程信息
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
这是我写的示例代码。红色圆圈的中间是以下三个过程的标识:
用户界面进程
通用后台进程:com.clock.daemon:bg
灰色保持活动进程:com.clock .守护程序:灰色
当然,这些进程的id也可以通过安卓工作室获得:
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
然后让我们得到三个过程的oom_adj:
1 at/proc/进程标识/oom_adj
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
从上图可以看出,用户界面流程和灰色保活服务流程的oom_adj=0,而普通后台流程的oom_adj=15。你也许能理解为什么普通的后台进程容易被回收,而前台进程不容易被回收。但是了解这还不够,那么请看下面的图片:
安卓进程保持活力的详细解释:一篇文章解决了你所有的问题
上图中,我将应用程序切换到了后台,并再次检查了oom_adj。您会发现用户界面进程的值从0变为6,而灰色的保活服务进程从0变为1。这里可以观察到,当应用程序退回到后台时,其所有进程的优先级将会降低。然而,用户界面过程是最明显的减少,因为它占用了最多的内存资源。当系统内存不足时,它必须优先终止这些高内存进程以释放资源。因此,为了避免后台用户界面进程被终止,有必要尽可能释放一些未使用的资源,尤其是图片、音频和视频。
从正式的安卓文档中,我们还可以看到这些不同类型的进程从高优先级到低优先级排列:前台进程、可见进程、服务进程、后台进程和空进程。这些过程是怎样的,它们是如何联系在一起的?我建议你阅读以下文章:http://www . cn blogs . com/angeldevil/archive/2013/05/21/3090872 . html。
本文摘要
写了这么多之后,让我们最后做个总结。回到开始时提到的QQ进程不朽的问题,我曾经想过有这样一种技术。不幸的是,在我拔掉手机后,我无法在结束QQ程序后再起床。一些手机制造商将这些知名应用放入自己的白名单,以确保这一过程不会因为改善用户体验而终止(例如,微信、QQ和Momo都在小米的白名单中)。如果他们被从白名单中删除,他们就像普通应用一样,无法逃脱被杀的命运。为了尽可能避免被杀死,让我们诚实地做优化工作。
因此,保持流程活动的基本方案最终还是回到了性能优化,而流程永远不会消亡的说法是完全错误的!
补充更新(2016年4月20日)
一些童鞋问,在华为的机器上,发现微信和Hand Q的用户界面流程退到了后台,oom_adj的值没有任何变化。里面有黑色科技吗?出于这个原因,我稍微验证了一下。验证方法是将演示项目的包名改为手机QQ,在华为的机器上编译运行,发现我的流程不会死。当我退回到后台时,oom_adj的值不会改变,但是不可能恢复原始的包名。所以,你知道,手Q在华为机器的白名单上。
本文源代码
请参阅本文的相关实务守则:https://github.com/52im/AndroidDaemonService
----------------------------------------------------------------------------------
哇谷im_im即时通讯_私有云_公有云-哇谷云科技官网-JM沟通
IM下载体验 - 哇谷IM-企业云办公IM即时聊天社交系统-JM 沟通下载
IM功能与价格 - 哇谷IM-提供即时通讯IM开发-APP搭建私有化-公有云-私有化云-海外云搭建
新闻动态 - 哇谷IM-即时通讯热门动态博客聊天JM沟通APP
关于哇谷-哇谷IM-提供企业即时通讯IM开发-语音通话-APP搭建私有化-公有云-私有化云-海外云搭建
联系我们 - 哇谷IM-即时通讯IM私有化搭建提供接口与SDK及哇谷云服务
公有云和私有云之间有什么区别?类似融云、环信云、网易云、哇谷云?