前台服务从奥利奥(Oreo)遇害

时间:2018-09-20 12:29:48

标签: android android-service android-source

我写了一个前台服务,该服务对于低于Oreo的所有OS版本均正常运行。关闭并从最近的应用程序中删除5分钟后,来自Oreo的应用程序进程将被杀死。

根据background execution limitations操作系统的android开发人员文档,不应杀死正在运行其前台服务且在通知窗口中显示通知的应用程序。

根据开发人员文档指南。我按照以下步骤启动前台服务。

  1. 前景服务以startForegroundService()方法启动
  2. 开始服务后5秒钟内,会使用startForeground()显示关于服务的通知
  3. START_STICKY的{​​{1}}返回onStartCommand()

我在以下手机上遇到此问题:

  1. OnePlus 5T
  2. Vivo
  3. Oppo
  4. Mi

我试图防止前台服务被破坏的原因是什么?

  1. 通过显示来禁用应用程序的battery optimization 系统对话框以禁止用户使用打ze模式。

我尝试重新启动前台服务是什么?

  1. 使用service从onTaskRemoved()重新启动服务。 请检查this link了解详情。

据我了解,这些制造商已经定制了AOSP,并且没有遵守允许前台服务运行的操作系统准则。可能是这些制造商之所以这样做,是因为为用户提供了较长的电池寿命。

前台服务类

AlarmManager

如果您遇到类似类型的问题并设法找到解决方案,请分享您的建议。

5 个答案:

答案 0 :(得分:11)

我已经在OnePlus上分析了该问题,因为我和您的处境相同。我目前看到的是没有解决方案。 OnePlus显然遵循了错误的做法。

由于他们还没有发布以这种方式杀死进程的源代码,因此我下载了OnePlus ROM(我选择了OnePlus 5T 5.1.5),将其解压缩,然后找到执行此操作的.class(服务中的OnePlusHighPowerDetector.class) .vdex),对其进行反编译,然后尝试找出正在发生的情况。

您可以在这里找到该类的版本(不是我本人的,也许不是我使用的同一版本):https://github.com/joshuous/oneplus_blobs_decompiled/blob/master/com/android/server/am/OnePlusHighPowerDetector.java

不幸的是,最重要的功能并未成功反编译。但是我们仍然可以分析字节码。这是我发现的东西:

  • OnePlus毫不留情地杀死了后台进程(似乎是否具有前台服务并不重要)。几乎所有人。占用多少CPU资源并不重要。我的应用程序使用率不到1%,并且被杀死。
  • 如果该应用固定在最近的应用列表(由com_oneplus_systemui_recent_task_lockd_list列表确定)中,则该应用不会被杀死。因此,用户可以通过固定应用程序来保存它。但这对他们来说不方便。
  • Oneplus提供了一个进程列表,它们不会终止。该列表位于oneplus-framework-res.apk/res/values/array.xml中,键为string-array name="backgroundprocess_detection_app_whitelist"。此列表主要包含地图和健身应用程序 1
  • 也许还有其他因素可以挽救被杀死的进程,但我没有进一步分析这个问题。如果有时间,请查看OnePlusHighPowerDetector.java。

以下是反编译.vdex文件所需的步骤:

  • 使用Vdex Extractor从.vdex创建.dex(也许您需要使用--ignore-crc-error选项)
  • 使用JADX反编译.dex(我认为这是目前最好的反编译器),或者使用dex2jar从.dex创建.jar,然后使用任何反编译器反编译。罐子

1 Rant:这表明当前情况有多严重。 OnePlus,这真的是解决方案吗?您选择了10-15个可以在后台运行的应用程序,并且您不关心其他所有应用程序吗?如何创建一个可以在您的设备上安全运行的新的Fitness / Map / Music Player应用程序?

答案 1 :(得分:1)

在服务内部使用startForeground(id, notification)方法。

用户应该知道某些无法被系统杀死的东西正在后台运行,因此android系统应该向用户发出通知,以便用户确切知道什么正在杀死其电池。

通过这种方式,您可以使用 WakeLock

 PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
 PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PARTIAL_WAKE_LOCK, 
 TAG_FOR_DEBUG);
 wakeLock.acquire()

但是在使用它之前,请先阅读有关 WakeLock 的信息。 而且,别忘了在工作完成后将其禁用。

您可以在终端

中使用adb shell dumpsys power命令检查当前启用的唤醒锁

答案 2 :(得分:1)

我花了几个小时解决这个问题。小米手机,奥利奥。我有解决方法,分2步:

  1. 小米还需要其他权限:设置->权限->自动启动。有允许自动启动的应用程序列表。 BOOT_COMPLETED和START_STICKY还不够。 Facebook,Outlook,Skype +我的应用已在此处列出。我不知道如何以编程方式要求用户授予此权限。

  2. 服务将重新创建,但不会重新启动,即使您返回START_STICKY。终止应用程序(从正在运行的应用程序中清除)后,将再次调用onCreate,但不会调用onStartCommand。尝试Log.d()查看它。我将所有逻辑转移到onCreate EXCEPT中,以创建通知,调用startForeground()并返回START_STICKY。这必须保留在onStartCommand()中。

也必须为应用程序禁用类别优化,但是以前的Android版本已要求进行优化。

现在,我的服务可以继续运行,或在几秒钟内成功100%成功地重新创建。

答案 3 :(得分:0)

我的应用程序OnePlus3遇到了同样的问题。然后,每次我的应用程序和前台服务被杀死时,我都会在logcat中注意到这些行:

10-12 18:30:40.644  1439  1519 I OHPD    : [BgDetect]force stop com.mycompany.MyAndroidApp (uid 10905) level 0
10-12 18:30:40.645  1439  1519 I ActivityManager: Force stopping com.mycompany.MyAndroidApp appid=10905 user=0: from pid 1439
10-12 18:30:40.645  1439  1519 I ActivityManager: Killing 23139:com.mycompany.MyAndroidApp/u0a905 (adj 200): stop com.mycompany.MyAndroidApp
10-12 18:30:40.647  1439  1519 W ActivityManager: Scheduling restart of crashed service com.mycompany.MyAndroidApp/md55852635cfc9dced970aa39ae09e74ead.MyForegroundService in 1000ms
10-12 18:30:40.651  1439  1519 I ActivityManager:   Force finishing activity ActivityRecord{a5c8d39 u0 com.mycompany.MyAndroidApp/md55852635cfc9dced970aa39ae09e74ead.MainActivity t3108}
10-12 18:30:40.655  1439  1519 I ActivityManager:   Force stopping service ServiceRecord{6052f94 u0 com.mycompany.MyAndroidApp/md55852635cfc9dced970aa39ae09e74ead.MyForegroundService}
10-12 18:30:40.660  1439  1519 I OHPD    : [BgDetect]chkExcessCpu level: 1 doKills: true critical false uptime: 300328
10-12 18:30:40.710  1439  8213 I WindowManager: WIN DEATH: Window{c381342 u0 com.mycompany.MyAndroidApp/md55852635cfc9dced970aa39ae09e74ead.MainActivity}

然后在互联网上搜索关键字“ OHPD:[BgDetect] chkExcessCpu级别:1 doKills:true”将我带到了这样的答案:

Prevent background service from being killed due to "detect excessive cpu on forked process"

根据该答案和GitHub问题的建议,锁定/固定我的应用程序可以阻止Oxygen OS杀死我的应用程序(MainActivity和Forground服务)。

答案 4 :(得分:0)

在oneplus 6t中,运行此adb命令

设置放置系统com_oneplus_systemui_recent_task_lockd_list {com.topjohnwu.magisk / a.c#0} {com.mycompany.MyAndroidApp / com.mycompany.MyAndroidApp.MainActivity#0}

防止杀死com.topjohnwu.magisk和com.mycompany.MyAndroidApp