let's assume we start a service from BrodcastReceiver on some broadcast. Can the process be killed after onReceive() returns and before service is started? And if so, how can this behavior be prevented?
If the BroadcastReceiver has called Context.startService() and it receives back a non-null ComponentName object, then no. That means the Service was found in the system and has been "started". Note that the start is asynchronous, so there's no guarantee that the Service has received its onStartCommand() callback before the receiver exits its onReceive() callback.
Also note that even though the BroadcastReceiver has started the Service, by default this has no effect on power management. So it is possible for your Service to not get called back until the device is fully up and running - it could go back to sleep after your BroadcastReceiver finishes but before your Service gets to run.
Related
I have tried using START_STICKY on the onStartCommand() method of intent services, I have even tried changing the process name of the service on the manifest.xml file. But none works. Whenever I kill the app, the service also gets destroyed. I want to design a service that gets triggered when the user starts the app for the first time and then keeps on running even after user kills the application. Any help will be useful
In service class implement on destroy method which will trigger a broadcast. In that broadcast receiver class implement on receive method. So whenever service destroyed this broadcast receiver class will execute onreceive method. In that onreceive method start the service again.
Your service must be in the foreground to prevent the system from closing it. See the startForeground method in the Service class.
I handle Service and the return code: START_NOT_STICKY. I do not want to restart the service.
But documentation says "Do not recreate the service, unless there are pending intents to deliver."
Could you give me an example of these pending intents that cause restarting the service?
When you return START_NOT_STICKY, this means the following:
If Android kills the process hosting your Service (which it can pretty much do at any time if it needs the resources or if it thinks your Service isn't doing anything useful), the following happens:
If your process is killed after onStartCommand() is called, but before onStartCommand() has completed, Android will restart your Service and call onStartCommand() again, redelivering the Intent that was being processed when the process was killed
If your process is killed after onStartCommand() has completed, Android will only restart your Service if there are pending Intents for your Service. In this case a pending Intent would exist if any component called startService() for your Service and that call has not yet been completely processed by your Service. This could be the case, for example, if a component called startService() while your Service was dead. Or it could happen if a component called startService() while your Service was still in the onStartCommand() method (processing a previous call to startService()).
I have a foreground service in which I register for location updates, and intent filter for the battery intent Intent.ACTION_BATTERY_CHANGED, and a LocalBroadcast. All of these I remove in the onDestroy of my service as once this service is dead.
I also have changed the return integer in the onStartCommand from START_STICKY to START_NOT_STICKY but this has no effect.
I log when this service is started and destroyed as well as my main activity and it seems that this service just starts on its own without any activities.
The issue is it's a foreground service so a notification accompanies it. This means that when it's started up again randomly, the user sees the notification and I don't want the service to be running on its own accord.
So to recap.
- It is a bound, foreground service.
- I return START_NOT_STICKY in onStartCommand
- When I no longer need it and close the app, I unbind from it, call stopService and the service's onDestroy is called which is where we unregister all of the receivers.
- The service is randomly started after this.
Since you use a foreground service, you should call stopForeground method
"Caution: The integer ID you give to startForeground() must not be 0."
There are only two ways to start a service, either binding or start it from a context, you must make sure you aren't doing it inside your code.
Maybe you should check on the service lifecycle:
http://developer.android.com/images/service_lifecycle.png
I am working on an application in android that starts a service on BOOT_COMPLETED. Everything is working fine, but while logging some messages I noticed that after I kill the application it starts up again anywhere from immediately to a minute later.
The only receiver that could be starting the service is registered to BOOT_COMPLETED. So my question is why is my application starting up on it's own after the phone has already booted up.
From the Android Site:
Broadcast Action: This is broadcast once, after the system has finished booting. It can be used to perform application-specific initialization, such as installing alarms. You must hold the RECEIVE_BOOT_COMPLETED permission in order to receive this broadcast.
To my understanding this event should only ever be broadcasting once so what else could be causing this event.
Edit: This is the code I am using in my BootReceiver (extends BroadCastReceiver) to start the service. This code is not duplicated anywhere else.
Intent serviceIntent = new Intent(context, RandomToneService.class);
context.startService(serviceIntent);
To check should I override it and Log it?
Not necessarily, but you need to read about services and their lifecycle.
What you are doing by swiping away the app from the recent-tasks list is the same thing that Android would do when your process gets terminated due to low memory conditions. A Service can request to Android that it be automatically restarted in those cases, and that is done through the return value from onStartCommand().
The default return value from onStartCommand() for a Service is START_STICKY, which tells Android to restart your service sometime later when there is memory. The default return value from onStartCommand() on an IntentService is either START_NOT_STICKY or START_REDELIVER_INTENT, depending upon whether or not you called setIntentRedelivery() and what you supplied there.
Hence, if you do not want your service to be automatically restarted in these conditions, you need to do something to get onStartCommand() to return START_NOT_STICKY, either:
Call setIntentRedelivery(false) on your IntentService, or
Override onStartCommand(), chaining to the superclass for default behavior, but then returning START_NOT_STICKY
I have a major Issue,
I make a Broadcast receiver which apply on the Device boot up, so i need to start a new service for performing long-running operation,
So in the onReceive() method of Broadcast Receiver I make a new Intent and by this Start a new service,
Now my problem is that this Service executes only for short time, as soon as the onRecieve() method finish it process is also finished and my Service is also stops with the finishing of Receiver process.
So how I can do this, to keep alive the Process of Service which starts from the BroadcastReceiver.
Now my problem is that this Service executes only for short time, as soon as the onRecieve() method finish it process is also finished and my Service is also stops with the finishing of Receiver process.
That would only occur if you are calling stopService(), or the service is calling stopSelf(). The service has an independent lifecycle from the BroadcastReceiver. It will not even be started before onReceive() ends.
but in the Service I use the Separate Thread, but this thread is also stopped.
That will only occur if you are stopping the thread yourself. Android does not know about threads you create.
Now, eventually, your app's process will be terminated. With a running service, this could take anywhere from 30 minutes to a couple of days, depending on what else is all going on with the device, whether you are using startForeground(), etc. Once the process is terminated, everything goes away, background thread and all.