how to make sure service is not killed

1.4k views Asked by At

I am trying to write a music player in Android, and was trying to use service to play music in infinite loop in background. And I need the service to interact with the activity for volume control and so on. The question is, if I use service binder then the service will likely to be terminated with the activity when the activity is in the background. How to make sure the service can keep running without the activity and in activity some of the service's method can still be called?

Is using foreground service with binder a solution? The service will not be killed in this way?

Thanks in advance!

2

There are 2 answers

0
ianhanniballake On

Per this process priority blog post, the only thing a higher priority than a foreground service is the foreground activity. This means that a foreground service will almost never be killed.

Per the building an audio app service documentation:

When a service is playing, it should be running in the foreground. This lets the system know that the service is performing a useful function and should not be killed if the system is low on memory. A foreground service must display a notification so the user knows about it and can optionally control it. The onPlay() callback should put the service in the foreground.

4
Noorul On

NOTE: Service will be run lifelong until you kill the service using stopSelf() or stopService() methods

Check your service is running or not using below method.

public static boolean isServiceRunning(String serviceClassName){
    final ActivityManager activityManager = (ActivityManager)Application.getContext().getSystemService(Context.ACTIVITY_SERVICE);
    final List<RunningServiceInfo> services = activityManager.getRunningServices(Integer.MAX_VALUE);

    for (RunningServiceInfo runningServiceInfo : services) {
        if (runningServiceInfo.service.getClassName().equals(serviceClassName)){
            return true;
        }
    }
    return false;
 }

For music player app you need to crerate bound service.check this docs docs

public class MusicPlayerService extends Service {
// Binder given to clients
private final IBinder mBinder = new LocalBinder();


/**
 * Class used for the client Binder.  Because we know this service always
 * runs in the same process as its clients, we don't need to deal with IPC.
 */
public class LocalBinder extends Binder {
    MusicPlayerService getService() {
        // Return this instance of MusicPlayerService so clients can call public methods
        return MusicPlayerService.this;
    }
}

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

/** method for clients */
public void play() {

}
public void pause() {

}
public void stop() {

}

}

in your activity class, declare mBound boolean variable,

boolean mBound;

add bindServiceImplementation

@Override
protected void onStart() {
    super.onStart();
    // Bind to MusicPlayerService
    Intent intent = new Intent(this, MusicPlayerService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
    super.onStop();
    // Unbind from the service
    if (mBound) {
        unbindService(mConnection);
        mBound = false;
    }
}

create To make communicate with MusicPlayerService class, initialize the ServiceConnection object,

  private ServiceConnection mConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName className,
            IBinder service) {
        // We've bound to MusicPlayerService, cast the IBinder and get MusicPlayerService instance
        LocalBinder binder = (LocalBinder) service;
        mService = binder.getService();
        mBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName arg0) {
        mBound = false;
    }
};

then you can call MusicPlayerService public methods like below,

  public void onButtonClick(View v) {
    if (mBound) {

        // However, if this call were something that might hang, then this request should
        // occur in a separate thread to avoid slowing down the activity performance.
       mService.play();
       mService.pause();
       mService.stop();

    }
}