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);
    }

定期报警接收器

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 活动进程 > tmp.txt

tmp.txt 中的条目 =>“Proc #1: prcp T/S/SF trm: 0 14790:my.app.package.indentifier/u0a172 (fg-service)”

以上条目基于此处接受的答案:前台服务被 Android 杀死

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

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

设备信息

型号:华为 GRA-UL00

EMUI版本:EMUI 4.0.1

安卓版本:6.0

其他注意事项:

内存不足,onTrimMemory 在终止之前不会被调用。无论如何,我将应用程序剥离到最低限度只是为了让应用程序在后台保持活动状态,因此这里的内存应该不是问题。

除非用户明确重新启动应用程序,否则粘性服务永远不会重新启动。

不调用警报管理器来重新启动/重新创建服务。setExactAndAllowWhileIdle() 也不起作用,并且应该无关紧要,因为该服务是前台优先服务,因此不应受打盹模式的影响。

服务在终止前最多只能运行 12 小时。发生这种情况时,电池电量超过 65%。

由于此应用程序用于研究项目,因此需要无限期地保持服务运行。

还有什么我可以做的吗,或者这是开发人员无能为力的特定华为 Android 修改。重申一下,这个问题只发生在华为设备上。

感谢对此的任何其他见解!

4

3 回答 3

0

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

于 2017-02-24T03:22:08.500 回答
0

你确定你需要唤醒锁吗?我有一个类似的服务,我注意到即使没有唤醒锁它也能工作。这篇文章声称杀手是唤醒锁。我已经尝试过我的进程,它曾经在几分钟内被杀死,现在已经运行了几个小时。

于 2017-02-11T18:11:25.750 回答
0

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

于 2017-11-01T11:12:45.823 回答