华为(GRA-UL00)上的前台服务被杀死 - 已启用受保护的应用程序

11

我的前台粘性服务在几个小时后被杀死,没有重新启动。我知道这已经被问过几次了,我已经阅读并验证了设备上的所有检查。需要注意的是,这似乎只发生在华为设备上。

因此,请允许我提供以下细节。

周期性服务

public class PeriodicService extends Service {
      @Override
      public void onCreate() {
           super.onCreate();
           acquireWakeLock();
           foregroundify(); 
      }

      private void foregroundify() {
            // Omitted for brevity. Yes it does starts a foreground service with a notification
            // verified with adb shell dumpsys activity processes > tmp.txt
            // entry in tmp.txt => "Proc # 1: prcp  T/S/SF trm: 0 14790:my.app.package.indentifier/u0a172 (fg-service)" 
      }

      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
           acquireWakeLock();
           if (!isServiceRunningInForeground(this, this.getClass())){
              foregroundify(); 
           }

           PeriodicAlarmManager alarmManager = PeriodicAlarmManager.get(this);
           alarmManager.setAlarm();
           return START_STICKY;  // after a few hours, service terminates after this returns. verified in my local logs 
       }

       @Override
       public IBinder onBind(Intent intent) {
          return null;
       }

       @Override
       public void onDestroy() {
            releaseWakeLock(); 
            stopForeground(true);
            super.onDestroy();
       }

    }

定期闹钟管理器

public void setAlarm() {
        Intent intent = new Intent(mContext, PeriodicAlarmReceiver.class);
        intent.setAction("repeat");
        mAlarmIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
        mAlarmManager.cancel(mAlarmIntent);
        long triggerAtMillis = System.currentTimeMillis() + ALARM_INTERVAL_MINUTES;

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerAtMillis, mAlarmIntent);
        } else {
            mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerAtMillis, mAlarmIntent);
        }

        ComponentName receiver = new ComponentName(mContext, PeriodicBootReceiver.class);
        PackageManager pm = mContext.getPackageManager();

        pm.setComponentEnabledSetting(receiver,
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
                PackageManager.DONT_KILL_APP);
    }

PeriodicAlarmReceiver

public class PeriodicAlarmReceiver extends WakefulBroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent service = new Intent(context, PeriodicService.class);
        service.putExtra("source", "PeriodicAlarmReceiver");
        intent.getAction()));
        startWakefulService(context, service);
    }
}

应用程序

    public class MyApp extends Application {

        @Override
        public void onCreate() {
            super.onCreate();
        }

        @Override
        public void onLowMemory(){
            super.onLowMemory(); // never gets called
        }

        @Override
        public void onTrimMemory(int level){
            super.onTrimMemory(level); // only gets called on app launch
        }

        @Override
        public void onTerminate() {
            super.onTerminate();
        }
}

adb shell dumpsys activity processes > tmp.txt

将上述命令输出的结果写入tmp.txt文件中,其中包含以下条目:"Proc # 1: prcp T/S/SF trm: 0 14790:my.app.package.indentifier/u0a172 (fg-service)"。此条目基于以下答案: Foreground service being killed by Android

在设置->高级设置 ->电池管理器 ->受保护的应用程序列表(允许应用程序在屏幕关闭后继续运行)中将MyApp添加到受保护的应用程序列表中。

在设置->高级设置 ->电源计划(性能)中使用性能(最低设置)。

设备信息

型号编号:HUAWEI GRA-UL00

EMUI版本:EMUI 4.0.1

Android版本:6.0

其他注意事项:

内存较低,无法在终止之前调用onTrimMemory。无论如何,我仅保留了应用程序的最基本功能,以使应用程序在后台保持活动状态,因此内存应该不是问题。

粘性服务只有在用户明确重新启动应用程序时才会重新启动。Alarm Manager不会被调用以重新启动/重新创建服务。setExactAndAllowWhileIdle()也无法工作,并且应该与服务为前台优先级服务无关,因此不应受到待机模式的影响。

服务只能运行最多12小时,然后被终止。当此问题发生时,电池电量高于65%。

由于此应用程序是研究项目,因此需要将服务无限期地保持活动状态。

是否有其他解决方案,或者这是华为Android修改的特定问题,开发人员无能为力。再次强调,此问题仅在华为设备上发生。

非常感谢您提供的任何额外见解!


嗨,秦正权, 你解决了华为6.0手机后台服务问题了吗?我在GCM和Google API客户端位置服务中遇到了同样的问题。 当应用程序从任务中终止时,它实际上会杀死进程,因此我无法获取位置更新。 - Md. Sajedul Karim
2
我并没有真正解决这个问题,但是通过以下方式,我成功延长了设备上的进程生命周期:
  1. 减少内存占用
  2. 降低功耗
  3. 使用前台服务
  4. 设置->高级设置->电池管理器->受保护的应用程序(允许应用程序在屏幕关闭后继续运行)- 没有办法绕过此步骤。您必须启用此选项,否则您的应用程序将无法在后台运行。
在华为手机上,我能够将应用程序在后台运行的最长记录是12小时,之后它就会被终止。
- Qin Zhengquan
1
谢谢兄弟。华为就是胡说八道。 - Md. Sajedul Karim
另外,定期在小米设备上观看此内容。顺便说一下,尝试使用IGNORE_BATTERY_OPTIMIZATION,可以参考我的建议。PS:小米MIU8从Settings.class中删除了ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS标志。自定义固件-糟糕 :) - Sergio
请展示启动服务为前台进程的代码。 - Sardar Khan
3个回答

0
华为手机有一个电池设置,但它与省电模式无关。在这个电池设置屏幕下,有一个名为“受保护的应用程序”(名称不确定)的子菜单。您需要允许您的应用程序受到保护,以防止华为在锁定屏幕后关闭应用程序。

1
嗨Jonz,我已经添加到受保护的应用程序中(请参见问题)。它在锁屏后在后台运行,最多可达12小时。问题是,与其他Android设备不同,我无法超过这个时间。 - Qin Zhengquan
在这段代码中,您没有将服务作为前台进程启动。 - Sardar Khan

0

你确定一定需要使用唤醒锁吗?我有一个类似的服务,发现即使没有唤醒锁也可以正常工作。这篇文章声称唤醒锁是罪魁祸首。 我已经尝试过我的进程,以前只能运行几分钟,现在已经运行了数小时。


0

听起来你的应用程序被华为PowerGenie杀死了,因为它无限期地持有唤醒锁。如果你无法避免使用唤醒锁,请参见我对类似问题的回答以获得解决方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接