5

is it possible to prevent Service(startForground) from being killed by os? I use it to play audio but it's killed when I use another app which requires more resources(Angry birds go) for a while. In logs I see app process being killed by ActivityManager. I replicated that also with some other audio apps. Only app which is not killed is Play Music app. It was replicated on samsung s3 android 4.3.

Martin Vandzura
  • 3,047
  • 1
  • 31
  • 63

3 Answers3

5

Is it possible to prevent Service(startForground) from being killed by os?

No. It's Android who decides which process has to be stopped when. The only way is to make it "less attractive for being stopped" by reducing amount of memory it consumes.

Save memory. Put the service into its own very small process. So that android os can kill the main process to reclaim memory and your service can keep running. Maintain a tiny service code by passing in setting and preferences with the intent used to start the service.

Note: tiny service must be a foreground service, meaning it has to show an icon in status bar.

manifest for seperate process

        <service
        android:name="com.gosylvester.bestrides.ServiceLocationRecorder"
         android:process=":bestRidesService" >
    </service>
</application>

pass in settings with the intent used to start the service. Simply restart the service to change the settings.

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    boolean isTrackerMarker = SettingMarker.TRACKER_MARKER_DEFAULT;
    if (intent != null) {
        // intent is processing = b
        isMiles = intent.getBooleanExtra(
                SettingApplication.APPLICATION_MILE,
                SettingApplication.APPLICATION_MILE_DEFAULT);
        isRecordAccuracy = intent.getBooleanExtra(
                SettingRecord.RECORD_ACCURACY,
                SettingRecord.RECORD_ACCURACY_DEFAULT);
        locationInterval = intent.getLongExtra(SettingRecord.RECORD_MIlLIS,
                SettingRecord.RECORD_PRESET_MEDIUM_MILLIS);
        startMillis = intent.getLongExtra(BUNDLE_START_MILLIS, 0);
        distance = intent.getDoubleExtra(
                ServiceLocationRecorder.BUNDLE_TRACKED_DISTANCE, 0);
        recordDistance = (float) intent.getIntExtra(
                SettingRecord.RECORD_DISTANCE,
                SettingRecord.RECORD_PRESET_MEDIUM_DISTANCE);
        boolean newIsRecording = intent.getBooleanExtra(
                SettingRecord.RECORDING, isRecording);

        isTrackerMarker = intent.getBooleanExtra(
                SettingMarker.TRACKER_MARKER,
                SettingMarker.TRACKER_MARKER_DEFAULT);
        startRecording(newIsRecording);
    }
sergej shafarenka
  • 20,071
  • 7
  • 67
  • 86
danny117
  • 5,581
  • 1
  • 26
  • 35
  • Thanks. I tried it. I put Service into different process but i was also killed by application manager after main process. I also set android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO); but it didn't help – Martin Vandzura Sep 04 '14 at 14:42
  • @vandzi keep searching sorry I wasn't able to help. – danny117 Sep 04 '14 at 17:42
  • I added a bit more details to the answer. Tiny service must be a foreground service. This reduces probability of being killed. There is no better solution for Android. – sergej shafarenka Feb 04 '15 at 05:57
2

Did you tried to request focus and control gain and lost of it? I think this app management is far from our control, but at least you can do something when this happens.

At some point of your app cycle, try something like this:

audioManager.requestAudioFocus(new OnAudioFocusChangeListener() {

        @Override
        public void onAudioFocusChange(int focusChange) {
            switch (focusChange) {
                case AudioManager.AUDIOFOCUS_GAIN:
                    // you have the focus, you can start or restarting playing
                    break;
                case AudioManager.AUDIOFOCUS_LOSS:
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                    // you lost the focus, you should pause or stop playing
                    break;
                case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                    // you lost the focus, but your app can continue playing in "duck" mode
                    break;
                 default:
            }

        }
    }, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
PFROLIM
  • 1,194
  • 9
  • 11
1

Take a look at the answer of Foreground service being killed by Android by Robin Davies, there's a lot of information:

Just to summarize, here's how things are supposed to work. Running services will be routinely scavenged and terminated every 30 minutes or so. Services that wish to remain alive for longer than this must call Service.startForeground, which places a notification on the notification bar, so that users know that your service is permanently running and potentially sucking battery life. Only 3 service processes can nominate themselves as foreground services at any given time. If there are more than three foreground services, android will nominate the oldest service as a candidate for scavenging and termination.

So perhaps there are more than 3 foreground services? He also explain about possible bugs in the platform when prioritizing foreground services.

Community
  • 1
  • 1
jjung
  • 230
  • 1
  • 4
  • 8