什么是Android进程(app)保活、进程保活的方案 |
您所在的位置:网站首页 › 安卓应用自启动什么意思 › 什么是Android进程(app)保活、进程保活的方案 |
想了解什么是Android 进程、Android 进程的生命周期、Android 进程回收策略 可参照地址什么是Android 进程、Android 进程的生命周期、Android 进程回收策略_lmm0513的博客-CSDN博客_android进程是什么 一、app保活在Android中是一种流氓行为,一方面无端浪费用户手机电量,另一方面给用户一种很困惑的感觉,影响用户体验还有可能导致整个Android系统流畅性变差,所以Google官方一种不推荐该功能,也一直在阻止这方面功能在Android系统上运行,作为一个Android开发人员,应该极力阻止这种无耻的行为!!! 以上内容原文:APP保活_qq_18350329的专栏-CSDN博客_app保活 二、Android 进程保活的两个方案:运行中保活:提高进程优先级,降低被系统 kill 的概率 被 kill 后拉活:被系统 kill 后,将进程拉活(重启) 1.运行中保活通过前面章节的论述,我们知道,假设 APP 进程能够一直被认为是前台进程,那么系统就有可能永远不会杀死该进程。当然,这是不可能的,当我们将 APP 退回到后台,改 APP 所属进程就不属于 前台进程了。但是上述假设也让我们有了灵感不是,只要我们尽可能的提高进程的优先级,不就可以最大概率的降低被系统 kill 的可能性了。 那么,提高进程优先级的方法有哪些呢? (1)利用 Activity 提高权限 监听手机锁屏解锁事件,锁屏时启动一个1像素的 Activity ,解锁时将该 Activity 销毁。此方法能将进程在锁屏状态下提高到最高前台进程( oom_adj 为 0 )的级别。避免出现一些让用户困扰(体验不好)的情况,该 Activity 需设计成用户无感知。 此方案主要解决为了达到省电目的,一些第三方应用或者系统管理工具在检测到锁屏之后一段时间(一般是 5 分钟)内会杀死后台进程。 下面是实例代码: 1像素 Activity: class KeepLiveActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) KeepLiveManager.keepLiveActivity = this // 设置Activity在左上角 window.setGravity(Gravity.START) // 设置window的像素为1 window.attributes.run { x = 0 y = 0 width = 1 height = 1 } } }注意,这里一定要设置启动模式为 singleInstance,使该 Activity 单独一个 Activity 回退栈,否则在锁屏且 APP 在后台运行时,启动该 Activity 后,会进程带入前台,解锁后显示该APP界面,体验不好 广播接收者: class KeepLiveReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { Log.d("KeepLiveReceiver", "action = ${intent.action}") when(intent.action) { // 锁屏 Intent.ACTION_SCREEN_OFF -> { KeepLiveManager.startKeepLiveActivity(context) } // 解锁 Intent.ACTION_USER_PRESENT -> { KeepLiveManager.finishKeepLiveActivity() } } } }管理单例: object KeepLiveManager { var keepLiveActivity: KeepLiveActivity? = null fun startKeepLiveActivity(context: Context) { val intent = Intent(context, KeepLiveActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK context.startActivity(intent) } fun finishKeepLiveActivity() { keepLiveActivity?.finish() } }注:由于锁屏、解锁的动作频率极高,该类广播在清单文件中注册无效,需要启动服务来注册广播,此部分代码和本章主题关系不大,就不贴代码了。思路就是:启动 APP 时,启动一个注册服务,在服务的 onCreate() 方法中注册广播,在 onDestory() 方法中注销广播。 以下是使用该方案保活前和保活后查看 oom_adj 的对比截图: 保活前 保活后 可见,保活后在锁屏状态,将进程的 oom_adj 由原来的7提高到了 0 。 附:查看进程 oom_adj 的方法 在命令行中使用以下两个命令 adb shell ps | grep packageName adb shell cat /proc/PID/oom_adj 如: G:AndroidGithubKeepLive>adb shell shell@armani:/ $ ps | grep com.cy.keeplive u0_a3 5991 213 541548 29976 ffffffff 00000000 S com.cy.keeplive shell@armani:/ $ cat /proc/5991/oom_adj 0(2)利用 Notification 提升权限 通过 setForeground() 方法可以将后台 Service 设置为前台 Service,可以将服务进程优先级提升为与可见进程一致,这将有效提高进程的优先级,从而大大降低进程被kill的概率。 通过 setForeground() 将后台 Service 设置为前台 Service 时,必须在系统的通知栏发送一条通知,也就是说前台 Service 必须绑定一条可见的通知。 在通知栏发送一条通知,是用户可以感知到的,这可能会对用户造成一定的困扰。可以通过实现一个内部 Service,在外部和内部 Service 中同时发送具有相同 ID 的 Notifacation ,然后将内部 Service 结束。随着内部 Service 的结束,Notification 也会消失掉,但系统的优先级仍然提高了。 @Override public int onStartCommand(Intent intent, int flags, int startId) { try { Notification notification = new Notification(); if (Build.VERSION.SDK_INT |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |