4

最近我们购买了一个新的带有 Android 5.1.1 的 Galaxy S6,我们在使用新的三星 SPCM 内存管理器时遇到了一些问题。它正在积极关闭我们应用程序的后台服务,即使设置为 START_STICKY,它也不会重新启动。

此外,该服务占用的 RAM 不超过 5MB,但不知何故,我们最终还是以 SPCM 算法的最低分数而被选择杀死。

这是我们的服务:

Public class IncomingService extends Service {

    @Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    return START_STICKY;

}

@Override
public void onCreate() {
    if (mPhoneListener == null) {
        mPhoneListener = new CallStateListener();
        TelephonyManager tm = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
        tm.listen(mPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}

    /**
 * Listener for call states
 * Listens for different call states
 */
private class CallStateListener extends PhoneStateListener {

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {
       // Doing something with incomingNumber
    }
}

在清单中:

    <service
        android:name="com.services.IncomingService"
        android:enabled="true"
        android:priority="999" >
    </service>    

SPCM 杀死我们的服务的日志:

Force stopping com.special.app appid=10499 user=0: SPCM kill lowestscore package!
03-18 22:48:11.280 3562-3562/? I/ActivityManager: Killing 2279:com.special.app/u0a499 (adj 8): stop com.special.app cause SPCM kill lowestscore package!
03-18 22:48:11.280 3562-3562/? W/ActivityManager: Scheduling restart of crashed service com.special.app/com.services.IncomingService in 1000ms
03-18 22:48:11.280 3562-3562/? I/ActivityManager:   Force stopping service ServiceRecord{27d2c408 u0 com.special.app/com.services.IncomingService}

即使 ActivityManager 日志指出它正在重新安排我们的服务的重启,它实际上从未被重启过。

我们已经看到有关其他应用程序(Facebook、TrueCaller 等)的相同 SPCM 日志,但它们的服务以某种方式设法重新启动。

综上所述,我们的问题是:

  1. 如何防止 SPCM 将我们的应用程序定位为最低分包?
  2. 如果我们被攻击了,如何确保我们的服务在被杀死后能够成功重启?
  3. 还有其他可以帮助我们的想法吗?
4

2 回答 2

0

确保ActivityManager 也没有针对您的服务

AFAIK 除了拥有持续通知之外,没有其他方法可以确保生存,这也是三星的开发人员文档所说的。至于 Facebook 和 TrueCaller,我没有答案。他们可能会利用其他相关流程来备份服务。

至于受影响的设备,我最早看到的是 5.0.2 的 Galaxy Tab S SM-T805。许多 5.1.1 三星设备也有 SPCM。我们最初也在 S6 上重现了这个问题,我可以确认它在 6.0.1 上仍然存在。

至于文档,这个三星论坛主题尽可能地深入。

对于测试和复制步骤,我建议:

  1. 确保设备实际具有 SPCM adb shell getprop | grep spcm
  2. 从任何电源上拔下它。
  3. 安装Tinycore以观察 RAM 使用情况(为其启用持久通知)。
  4. 加载大量需要 RAM 的应用程序以降低您的服务分数。或者尝试使用Developer Toolbelt,它应该比手动填充要快,但我还没有测试过。
  5. 关闭屏幕并给设备 15 分钟。
  6. adb shell logcat -v threadtime | grep spcm确认进程被杀死。
  7. 冲洗并重复直到成功。
于 2016-05-18T12:41:08.193 回答
0

我会尽力帮助你回答你的第三个问题:

我面临同样的问题,我发现最好的解决方法是使用 AlarmManager 来启动我的服务。所以我将 AlarmManager 设置为每 30 分钟运行一次并启动我的服务。如果它仍在运行,将再次调用 onStartCommand,否则将重新创建服务。我对我的代码进行了一些调整,以处理每 30 分钟对 onStartCommand 的新调用,它的工作方式符合我的预期。缺点是电池消耗,因为我的服务一直在运行,Android 永远不会进入睡眠模式(仍在工作)。另一种方法是将您的服务设置为在前台运行,但在我的情况下,我不想这样做。

您可以尝试禁用 SPCM,打开 build.prop 并更改以下行(需要 root):

sys.config.spcm_enable=true

至:

sys.config.spcm_enable=false

看看这里这里

希望能帮助到你。

于 2017-01-26T12:56:43.170 回答