Android foreground service being killed under cert

2019-07-18 05:42发布

问题:

I have a Service used for playing audio. It is created with START_STICKY, and calls startForeground() when it is told to play music, and stopForeground() when it is told to stop playing music.

The service continues to run fine and play music, even after the app is swiped out of the task manager on 4.2.1. However, the service is inexplicably killed if the app is swiped out and the app's home/lockscreen widget is interacted with or if I try to sendBroadcast() within the service.

I cannot find anything that would cause a crash, no low memory warnings, the Service is not bound to anything, just:

10-09 17:14:42.186: I/ActivityManager(2591): Killing 18400:com.xperia64.timidityae/u0a10079: remove task
10-09 17:14:42.236: W/ActivityManager(2591): Scheduling restart of crashed service com.xperia64.timidityae/.MusicService in 5000ms

The dumpsys activity services command always produces this, as it should be:

Proc # 8: adj=prcp /FS trm= 0 22326:com.xperia64.timidityae/u0a10079 (fg-service)

My app does some heavy JNI MIDI->wav processing, but even if I play a basic MP3 with a MediaPlayer, the killing of the service still occurs. Also, I have a custom notification with buttons if that makes a difference. I have also tried forcing a PARTIAL_WAKELOCK, but that did not help either.

回答1:

Found this workaround here: https://code.google.com/p/android/issues/detail?id=53313#c1

In the foreground service:

@Override
public void onTaskRemoved( Intent rootIntent ) {
  Intent intent = new Intent( this, DummyActivity.class );
  intent.addFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
  startActivity( intent );
}

In the manifest:

<activity
  android:name=".DummyActivity"
  android:theme="@android:style/Theme.NoDisplay"
  android:enabled="true"
  android:allowTaskReparenting="true"
  android:noHistory="true"
  android:excludeFromRecents="true"
  android:alwaysRetainTaskState="false"
  android:stateNotNeeded="true"
  android:clearTaskOnLaunch="true"
  android:finishOnTaskLaunch="true"
  /> 

In DummyActivity.java:

public class DummyActivity extends Activity {
    @Override
    public void onCreate( Bundle icicle ) {
        super.onCreate( icicle );
        finish();
    }
}


回答2:

Here's a workaround that seems pretty reliable and doesn't close the recents screen when your swipe the app's task away:

In every broadcast sent by your app to your app (also including PendingIntents), add the Intent.FLAG_RECEIVER_FOREGROUND flag to the intent being broadcast.