Foreground Service killed on Huawei (GRA-UL00) - P

2019-04-06 16:21发布

问题:

My foreground sticky service is killed after a few hours without being restarted. I know this has been asked a couple of times, and I have read and verified all the checks on my device. Its important to note that this seems to occur only on Huawei devices.

So allow me to provide the following details.

Periodic Service

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

    }

PeriodicAlarmManager

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

Application

    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

Entry in tmp.txt => "Proc # 1: prcp T/S/SF trm: 0 14790:my.app.package.indentifier/u0a172 (fg-service)"

Above Entry is based on accepted answer here: Foreground service being killed by Android

Added MyApp to protected app list in Settings-> Advanced Settings -> Battery Manager -> Protected Apps (Allow app to keep running after screen is turned off)

Used Performance (lowest setting) in Settings-> Advanced Settings -> Power Plan (Performance)

Device Information

Model Number: HUAWEI GRA-UL00

EMUI Version: EMUI 4.0.1

Android Version: 6.0

Other Notes:

Low Memory, onTrimMemory is not called prior to termination. In any case, I stripped the app to its bare minimum just to keep the app alive in the background, so memory should not be an issue here.

Sticky Service is never restarted unless user explicitly re-launches the app.

Alarm Manager is not called to restart/recreate service. setExactAndAllowWhileIdle() does not work either, and should be irrelevant since the service is a foreground priority service, and hence should not be affected by doze mode.

Service can only run at the maximum of 12 hours before being terminated. Battery was above 65% when this happened.

It is a requirement to keep the service running indefinitely as this app is for a research project.

Is there anything else I can do or is this a specific Huawei Android modification that the developer can do nothing about. To reiterate, this issue only happens on Huawei devices.

Appreciate any additional insight on this!

回答1:

Are you absolutely sure you need the wakelock? I have a similar service and I have noticed that it works even without the wakelock. This post claims that the killer is the wakelock. I have tried with my process which used to be killed in minutes and it has now been running for hours.



回答2:

Huawei -> have a battery settings, but it's not about power save mode. under this battery settings screen, there is sub-menu call "Protected App" (not sure the name). you need to allow your app to be protected to prevent Huawei kill app after lock the screen.



回答3:

It sounds like your app is being killed by Huawei PowerGenie because it holds a wake lock indefinitely. If you can't avoid using a wake lock, please see my answer to a similar question for a workaround.