I have a Service which handles downloading a list of simple files which it receives via the intent upon creation. I stop the Service once all the items have been downloaded. However if the System decides to kill the Service, upon recreation (because of START_STICKY) I will receive a null intent (http://developer.android.com/guide/components/services.html#START_STICKY). Is there a way to continue on where the Service was stopped without having to manually persist the list.
You could use the flag START_REDELIVER_INTENT, which will call again the onStartCommand method of the service with the last sent intent if the service's process is killed before it calls stopSelf. Anyway I don't know how and what your service exactly does, so it could be that you still have to save in a persistent way some information.
Related
Say I have an Activity that launches a Service using startService() when user presses a button. The service is stopped using another intent in startService() when user presses another button, or it can decide to stop itself. The service wants to run forever, so it returns START_STICKY from onStartCommand(). While the service is running, it connects to some server and receives messages. Activity binds to it and, when bound, displays those messages.
Now, when the Activity is started after an OOM kill, it doesn't know if the Service is started. One can use a static field set in onStartCommand() to tell if the Service is running, but that's prone to backfire sooner or later. Moreover, the Service can be started by the system after the activity has been launched, so using a static field is not an option at all.
The cleanest solution I can come up with is using SharedPreferences to store the state of the service. This is going to fail to be good when the service is killed between SharedPreferences.setBoolean("running", false) and stopSelf(), but such a thing will probably occur rarely.
Also I can try to bind to the Service at all times. This would be very ugly but still not impossible.
Any other solutions? Maybe the very idea is wrong in some way?
I was using a service which will update my application whenever new update is available in server. So my service run and it always check with server for version update and if i get new version update it will install.
My issues whenever i closed my application form taskmanager my service is getting killed. I used START_STICKY in onstartcommand() also even though it is not working. Is their is any chance to restart my service once it is stopped by taskmanager.
You can use AlarmManager to periodically wake up your application (i.e. activity or a service). This way you won't need to run service in the background all the time.
Just set AlarmManager to wake your app/service every day/week, check for an update, and then close the service. Check out this tutorial on how to use AlarmManager.
This approach will be better than running your own service, because it'd use no memory or battery power. Your users will thank you for that!
If your application is designed to run on API level 21 or newer (which means Android 5.0 Lollipop), you can also take advantage of JobScheduler. It might be useful, i.e. it could schedule update check to run when device is plugged in, to further save power.
From the docs:
Notice that the onStartCommand() method must return an integer. The integer is a value that describes how the system should continue the service in the event that the system kills it (as discussed above, the default implementation for IntentService handles this for you, though you are able to modify it). The return value from onStartCommand() must be one of the following constants:
START_NOT_STICKY
If the system kills the service after onStartCommand() returns, do not recreate the service, unless there are pending intents to deliver. This is the safest option to avoid running your service when not necessary and when your application can simply restart any unfinished jobs.
START_STICKY
If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand(), but do not redeliver the last intent. Instead, the system calls onStartCommand() with a null intent, unless there were pending intents to start the service, in which case, those intents are delivered. This is suitable for media players (or similar services) that are not executing commands, but running indefinitely and waiting for a job.
START_REDELIVER_INTENT
If the system kills the service after onStartCommand() returns, recreate the service and call onStartCommand() with the last intent that was delivered to the service. Any pending intents are delivered in turn. This is suitable for services that are actively performing a job that should be immediately resumed, such as downloading a file.
Have you tried to return the onStartCommand() with START_REDELIVER_INTENT ?
You can owerride this method onTaskRemoved to start service again via BroadcastReceiver.
I have a Service running in the foreground, and an Activity that interacts with it. If the Activity crashes, Android kills the entire process, including the foreground Service and its associated Threads.
However, the ongoing notification provided by the Service does not go away, and upon closer inspection, Android's task manager reveals that the Service itself is still running.
How can I kill the foreground Service in this circumstance?
Have you override onStartCommand method of the Service? What value is it returning? If not, try to override it and return START_NOT_STICKY from it.
START_STICKY: If this service's process is killed while it is started, then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service.
START_NOT_STICKY: If this service's process is killed while it is started, and there are no new start intents to deliver to it, then take the service out of the started state and don't recreate.
Not sure, as I have never worked on foreground services, but this might be the reason.
Are you sure the service is not running it its own process...
Also can you confirm whether the service is getting restarted..If its getting restarted-it is because you are returning START_STICKY from onStartCommand()
I have an app with a main Activity. I add data into a list in a service using a binder. At the same time, I start the service which runs in the background. When I close and restart the app, my list of data in the service is destroyed. Why does this happen?
Perhaps your service was killed and if You used START_STICKY it was just restarted without any parameters (as standalone service). I think you should somehow persist information that service was invoked with parameter and save it e.g. to the database. When service finishes dealing with your data, delete that information and allow it to be invoked once again.
Because it is in the started state, it will guarantee to call
onStartCommand(Intent, int, int) after creating the new service
instance; if there are not any pending start commands to be delivered
to the service, it will be called with a null intent object, so you
must take care to check for this.
When you bind to a Service, the lifecycle of the Service is depending on the one that does the bind (in your case the Activity). So if you do a unbind in onPause/onStop the Service will be destroyed.
If you start the Service using START_STICKY it will be alive until stopped by user in code or by Android OS (when it needs resources.
(Depending what you really need), I would suggest is store it in SharedPreferences or in an other way (e.g. SQLite DB). To prevent losing data when something kills or stops the Service.
Normally your service is not destroyed every time, but if other application needs more resources and device doesn't have it, OS can stop you app.
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