August 13, 2021

Service killed automatically

By lj007

Service is a component which works on main thread but without UI!!. It is true, service don’t have UI(If not foreground). There is many reasons you may want your code running without directly affecting user process. Keep in mind that service not works in background, it will always work on main thread. You need to handle long running task to handle ANR state or you can go with IntentService or AsyncTask or Thread, which works on worker thread.You can check about service here. There is many cases where you need to create background service for app, in this situation you need to know verify that is your service is running always or longer time!!Android have such a good mechanism to manage device memory. Android can kill your service and you don’t know that your service killed by OS.

Why android kills my Service?

A good question, but you already know why it kills. Your services killed because, OS needs more resource for current user activity and your service is likely to release resource.

How to know is my service is likely to killed?

Android docs gives you good clarification on that. You need to check here and define that whether your service is killed by OS or not!! 
Here, I am sharing my experience with Service. I am developing app with continues user tracking for more than 8 hours, or you can say full day. I am starting service with startSerivce(context, MyService.class). This will run full day if OS don’t requires more memory which can get from killing my service. You can check how I have defined my service here:

class LocationTracker : Service() {
    override fun onBind(p0: Intent?): IBinder? = null
    

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        doYourWork()
        return START_REDELIVER_INTENT
    }
}

You notice that is not java code, it is kotlin. As android decided to approve kotlin as official language for development I moved. You may have noticed that I have user START_REDELIVER_INTENT, You can check what it used for by clicking on that. You also have to specify it in Manifest file. I have declared it like below, because I want it work in another process.

<service android:name=".locationtracking.services.LocationTracker" android:process=":tracking">
</service>

My service should run all time, until I don’ t stop it with stopService. But what happens if OS need more resources for current opened activity? Right, it will stop this service and free some resources.
Once OS is idle and depending on service status, OS will restart service, in my case it will redeliver my Intent and restart service. What about those devices, which always runs on low memory? Our service will not works for long time.
One time you can think about starting service from it’s onDestory() method, but how do you know onDestroy() will called on lowMemory situation? onDestory() method will not call if service is killed by OS or by User by going to settings and killing service explicitly. With service you also need to define android:description  for user to know this is your service and why you are running this service.

So there is no solution?
There must be solution. I will come back soon with my solution which I have used to prevent this. Android don’t give full authority to handle device but you can workaround for that. Before going to solution please check once again, you really need that service which will always running in background. You can also use FCM, AsyncAdapter or JobScheduler to do your job. These are also battery efficient and more powerfull than full-day  running service.