Prioritize scheduling restart of crashed android service - android

By using START_STICKY , if my service is crashed/killed by task manager, it automatically restarts. I see that there are a list of services which gets restarted but in a different order. I want to prioritize this restarting of the service so that it will start sooner by placing to the front of the queue.
It typically takes 15 seconds to 45 seconds to re-start the service. Is there a way to prioritize or start this service sooner than the other.

Is your service long running? If it is, try to get rid of it and only start it when it is needed. Android services are not meant to run as a daemon, they are meant to run as short living workers in the background when no user interaction and interface is needed.
Most of the "I'm just sitting around" services can listen to broadcast intents and be a nice citizen this way.
Another thing: If your service is already short running and the a task killer is active, it's easy: It's the users problem and not your fault. The system doesn't need task killers and you shouldn't take care of them. The user should know that it's not healthy to use them.

I guess this solution is a little bit dirty, but you could use a new Service that starts with START_STICKY and set all other services to START_NOT_STICKY.
You could then use the new service to start all other services (though this is not necessarily needed). This is actually an easy implementation, as you can pass the whole intent to the service that shall be started.
Then you could add a Broadcast on all service's OnDestroy() to tell the new service, that one of the old was killed by the system. You can also pass the old starting intent via OnDestroy(), so it gets restarted.
In case your new service gets killed, you can check after restarting if any of the other services was killed, too and then prioritize the restarting.

Related

How to have a continuous running background task on Android?

I'm fighting with the Android desire of killing everything which isn't active on the screen. My problem in few words:
I have a microcontroller which communicates with a processor on which Android runs;
the processor must keep active a watchdog on the microcontroller, resetting periodically (every one second) one of its registers; an application, say App B, accomplishes this duty;
on the processor I can be sure about the persistent existence of another application, say App A (or, however, if App A dies App B can die too because the system is compromised) which for now does nothing, in the future will accomplish other duties.
Which is the best way to implement App B?
I tried the following solution: App B contains a Bound Service, say Service A, to which App A can bind on; Service A starts a thread, say Thread A, which periodically resets the microcontroller watchdog. Thread A is launched when app A sends a command to Service A (e.g. START_WATCHDOG).
In my idea, Service A lives until App A lives (thanks to the binding), and so the process to which Service A belongs lives, and so also Thread A.
Unfortunately, from tests I see that sometimes (in a sporadic manner), after some time (sporadic time, too), with almost no work running on the system (except for App A, Service A and Thread A) the system kills Service A process, and so Thread A stops and the watchdog elapses.
When Service A dies, it is restarted (because it is a Bound Service and App A is still running) but, for now, I don't save the current state of Service (which simply consists on the START_WATCHDOG command arrival or not) and this is the reason for which the watchdog elapses.
So, I've got several questions about my solution:
is it ok and I simply need to save the current state of Service A in order to restore it when restarted?
should I discover better the reasons for which Service A, or better its process, is killed?
is there a better solution for my problem?
Thank you very much to everyone who will spend some time to help me.
Being not sure about periods in which your service runs you can try these:
Use foreground service. However, you might need to acquire a wakelock within your service start point if you need cpu in long time. Plus, a notification needs to be shown on phone status bar.
Use WorkManager-new api part of jetpack simplifying the use of alarm managers and jobschedulers- to schedule your tasks periodically. However if your frequency is higher than 1 per 5-10minute then you will need to take care of doze mode. If phone gets into doze, your tasks might be delayed till maintenance periods. A trick to apply here might be starting a foreground service when you catch activation of doze mode and return back to Workmanager logic in deactivation(if you don't want user to see the foreground service's notification). Do whatever you want in the foreground service like.
Use Firebase Cloud Messaging to push notification from your server to your users periodically for you to have a small amount of time to do work in background. When notification comes, OS grants you an interval to run a task.
Use Work manager it is easy to implement.

Make a service run indefinitely and communicate with activity

I Can't understand the differences on android services
I want to have a service run all the time in the background (activity recognition)
When it detect that I RUN -> open GPS -> save curent longitude latitude -> if I stopped to run (WALKING) -> display the log lat on my MainActivity
i want the service run if the user close the app , if the device is closed and re-open , if my service is killed
so I read about:
[Started Service , Intent Service , Bound Service , Intent Bound Service , Job Scheduler , Job Intent Service].......But still i missing something
I understand that with Service start_sticky for API<26 will run forever (if not killed) and with IBinder I can update the UI of my MainActivity; right?
My Many Q are ...:
1. Bound services can run for ever? and update my UI of MainActivity? do i need bound or i can achieve this with service or intent service
2. For oreo I "must" use Job Scheduler -> when killed -> open again with broadcast receiver || work manager || alarm manager ||?
My questions are more for theory Answers not code.
NEED to -> service for "ever" run -> if (something) -> open gps -> save long lat -> show long lat in UI of MainActivity.
To keep a Service running indefinitely in the background, use a foreground service. This will force you to maintain a visible notification/nav bar icon; that's the price Android extracts from you in exchange for keeping your service running for a long time period. Supported on API 5+.
JobScheduler/WorkManager/AlarmManager won't prevent your Service from being killed. They can be used to bring your Service back to life. Also, JobScheduler and WorkManager can get your system out of doze, so you can do useful work. A WakeLock may also be necessary. If the user explicitly terminates your app, JobScheduler jobs will no longer wake it up. I don't know of any good, "Android-approved" way to resuscitate an app in this circumstance. Although, even on Oreo+, you can register to receive these intents, which you can use to regain execution.
You can make any of the Service subclasses you mentioned into a foreground service (by calling startForeground(). The choice of subclass is a matter of convenience, and depends on how you would like to dispatch & schedule your work. Your app could just as easily be implemented with the base-class Service.
START_STICKY doesn't actually prevent a Service from stopping. It's more like a request to the system: "After you kill my app/service, please restart it, if/when you see fit". In my opinion, it is not an effective way of keeping a Service running for a long period of time. If a Service is not in the foreground, and no other application components are in the foreground (e.g., on screen), then Android can kill your app quite quickly. This is more true of later versions of the OS (Oreo+).
Your Service will need to be bound to other components (e.g., Activities) from time to time. You bind to a Service so you can 1.) Make sure it exists and 2.) Carry out communications with it (call functions on it, etc.). So, yes, with IBinder, you can update the UI of your MainActivity.
Binding a Service doesn't make it run forever. If your Activity is bound to the Service, you can be confident that the Service will stick around for as long as the Activity is onscreen. Once it leaves the screen, all bets are off.
In other words, Android is very likely to kill an app/service when it's not in the foreground, and not bound to any components that are in the foreground (onscreen).
A Service can generally open up an Activity at any time it chooses, simply by calling startActivity(). Your Activity can even dismiss the keyguard (in certain circumstances), using FLAG_DISMISS_KEYGUARD.
If you can tolerate less frequent location updates, you may be able to do this without staying in the foreground, but there are limitations.

Terminate android service without reset

I am aware that force killing an app is very bad, but the client requires it. I am required to implement a force reboot of sorts for the app. This is how I implemented it:
I create a BroadcastReceiver in my Application's (not Activity's) onCreate method. I have it wait for the REBOOT command to be broadcast. Upon receipt, I have it broadcast another message that has the services call stopSelf so that threads and services have a chance to exit cleanly. I then have an AlarmManager call my main activity 5 seconds later. Finally have my application kill itself with Process.kill(Process.myPid()). For the most part, it works, and I just need to add some extra waiting time before it kills the process (maybe by waiting for a TERMINATE broadcast from each running Service). My issue is this: while reviewing the logs, I found out that the system schedules the services to reboot. I'm worried about conflicts. Is there a way to terminate the services without any chance of it rebooting?
I fixed this by having the Receiver wait for all the services to finish their onDestroy() calls before having it die. I also changed from Process.kill() to ActivityManager.killBackgroundProcesses().
As a side note: I know it's wrong, but it really does feel cool killing the processes hehehe.

What happens to a service started by BOOT_COMPLETE after system kills it?

What happens to a service started by BOOT_COMPLETE after system kills it for memory?
Will it ever be restarted without rebooting the phone? Is it possible to restart it somehow?
What is the best practice to avoid as much as possible an important service from being killed?
Will it ever be restarted without rebooting the phone?
Possibly. If it truly was because "system kills it for memory", and you return an appropriate value from onStartCommand() (e.g., START_STICKY), it should be restarted at some point in the future. If the service was killed due to user action (e.g., Force Stop in the Manage Services screen in Settings), it will not be restarted.
What is the best practice to avoid as much as possible an important service from being killed?
First, design your application to not rely on an everlasting service like this. 99.44% of Android applications do not need a service that runs continuously, let alone one that starts doing so at boot time. Android device users hate developers who think that their apps are sooooooooooooo important that they have services running all the time -- that's why we have task killers, Force Stop, and Android killing services due to old age. For example, if you are checking for new email every 15 minutes, use AlarmManager and an IntentService, not a service that runs forever.
If you can demonstrate -- to me and to your users -- that yours is among the 0.56% of applications that really do need a service that starts at boot time and runs forever, you can use startForeground(). This will indicate to the OS that your service is part of the foreground user experience. You will have to display a Notification, ideally to allow the user to shut down your service cleanly if and when the user no longer feels that it is justified.
If you need to restart the service then you should use AlarmManager to check up on the service in a separate BroadcastReceiver, but nominally when a service is killed by the system for memory it will not get automatically restarted.
You may want to take a look at START_STICKY
Use the AlarmManager to periodically send an Intent-- receive the intent and make sure your service is running.

Android Development: Service get killed

I've got a running service. But when taskmanager kill the Activivty that starts the service the service get killed to.
Why do my service get killed when the taskmanager kill the activity not the service?
There is no "taskmanager" in Android, at least by that name.
If you are running Android 2.1 or older, third party applications that describe themselves as "task managers" or "task killers" can terminate your entire process, and more besides, which will get rid of your service.
If you are running Android 2.2 or newer, while "task managers" have a somewhat reduced role, the Settings application in the OS allows users to force-stop any application or individual service.
IOW, what you are seeing is perfectly normal and something you need to take into account. Users do not like services running for long stretches of time, unless they perceive value from those services being there. So, for example, a user who kills the service that is playing back music quickly learns not to do that anymore. But, if the user does not know what value your service is adding, and your service is running a lot, expect it to be shut down by the user.
As a result, savvy developers architect their applications to avoid long-running services. For example, if you are checking the Internet for something (e.g., new email) every 15 minutes, rather than have a service running all of the time, use AlarmManager to start up your service every 15 minutes, and have that service stop itself once the Internet check is complete. This gives you the same functionality, but you stay out of memory most of the time.
Complementing CommonsWare: if the only reason for your Service to exist was that it was bound to the activity, when that activity is killed there is no longer a reason for the service to exist, hence it could be killed.
(I thinking in bound services in here! http://developer.android.com/guide/topics/fundamentals/services.html)
Update
Based on your comment, I see that you are using a "Started" service. In that case I recommend you to implemente the service in a separate class, not as an inner class within the Activity class. This could be what was causing your problem.

Categories

Resources