I'm creating a service that runs in the background. It does the following:
Gathers the user's data (with permission)
Runs certain tasks every X minutes, and sends this data to a server every Y minutes
I'd like if other people could write their own UI, widgets and other cool stuff.
Currently, the service continues to run between task runs/network sends (without a wakelock).
The service listens for validation and runtime changes; this requires a separate process. There are ways around this but they would involve using IPC (which I don't think would cause a big performance hit).
Questions:
Should the service be allowed to die between tasks or should I let it run without a wakelock?
Is it more effective to remain alive than to open a database every minute or so?
Can people use my service if it's not in a separate process?
The question the arises, should my service be in it's own process?
No. By which I mean it should run in the same process as all your other components.
I think it'd be nice if other people could write their own UI, widgets and other cool stuff.
It doesn't have to be in a separate process for this right?
No. It will automatically be in a separate process from the code from the "other people".
Right now the service stays running between task runs/network sends (not keeping a wakelock though) as I figure it will be more effective than opening a database/doing setup every minute or so.
Your users may disagree with this plan. Everlasting services are the reason why users attack developers with task killers and force-stops from the Settings app.
Should it be allowed to die between or should I let it run without a wakelock?
I recommend that you use an IntentService (since you need the background thread anyway for the network I/O) and let the service shut down in between polls. Also, please allow the user to control the values of X and Y from your opening paragraph.
Tasks run on an interval, should my service die in between (having to reopen the DB)?
Generally, yes. Opening the database takes a very small amount of time (e.g., handful of milliseconds), unless the flash storage is busy. That is a small price to pay to avoid complaints from users about your service running all of the time.
Can people use my service if it's not in a separate process?
Yes, so long as you are exposing some API (AIDL, documented set of Intents to send as commands via startService(), etc.).
It seems to me it might be worth dedicating an app purely to the service (i.e., no other components except a 'settings' Activity) and do everything through Intents.
As long as the manifest has all possible Intents registered using <intent-filter> blocks, anyone can communicate with it (your own apps as well as any 3rd party apps).
Also, you might want to use an IntentService which will process commands as they arrive and then shut itself down when finished.
Without fully understanding your requirements, i.e., what exactly the service is processing, it's difficult to advise further.
Related
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.
I'm writing my first independent Android app. It will sit in the background and respond to a few events generated by the OS, somewhere between a few times a day to a few times a week depending on the user.
Coming from a PC programming background, I thought I might need a service, but Android Developers > Service says:
What is a Service?
Most confusion about the Service class actually revolves around what it is not:
A Service is not a separate process. The Service object itself does not imply it is running in its own process; unless otherwise specified, it runs in the same process as the application it is part of.
A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
The app should not need to consume any resources unless one of the events it's listening for happens. The user should also not need to actively use the app after it's been set up, only if they want to change its settings.
I have games that seem to do something similar to what I want. They sit in the background and can receive messages (e.g. it's now my turn), and when I click on the notification it loads the game into memory, which takes a few seconds longer than if it was already in memory.
If the user hasn't used the app's interface for a month, I want it to still be in operation (even if the device has been power-cycled) and respond to events but not to appear in the list of recent apps (assuming a month is long enough to push it off the end). Ideally, I want it to respond to the events within one second; it doesn't have to be near-instant. What's the normal way this is done?
An app (occasionally used) and a separate "service" process/thread (persistent)
A combined app and "service" (persistent)
A combined app and "service" (loaded into memory by events)
Not enough reputation to comment, but just to tell you that nothing prevent Android to kill your service, To restart your service after the user reboot its phone you can add a broadcast receiver and listen to
https://developer.android.com/guide/components/broadcasts
.Also, if you don't want to display a notification while your service is running you will have to use a background service instead of foreground one. Hope this help.
I'm building a monitoring app that will capture as much info as possible from the mobile device, like running processes / active connections / networking statistics / active interfaces etc. Obviously I will need a service that will be running in the background for that, but I'm not entirely sure how to implement it.
Someone suggested that I create an IntentService that will execute at specific intervals using AlarmManager, do its thing and then die again.
In this thread people suggest an implementation using an always-on Service that starts its own thread to do the work, put it to sleep and then again. One also suggested that AlarmManager is used too to make sure that the service will be restarted if the OS kills it.
What's the mpst appropriate implementation for monitoring real time data? (or the up/downsides of each). Note that many of the info I'm capturing do not produce intents (so I can't just register receivers)
Thanks a lot:)
Note that many of the info I'm capturing do not produce intents (so I can't just register receivers)
Then you won't be able to use an IntentService, since your app won't know when to fire it up.
If you want "real time" updating of info, then you will have to use a Service (with or without it's own background thread). You cannot use an AlarmManager because it will almost always run too late (not "real time").
Do note that it takes some effort to have your service run always as there are a couple of different scenarios where it can stop running, and even when you have done all you can to achieve it, there are still ways for OS or user to stop it from running.
Android services might get killed by the operating system at any possible time. There are no guaranteed lifecycle calls like onDestroy() you can rely on. I have to implement a service doing a lot of long running tasks and a bunch of file operations in the background. So my questions are:
Is it generally a good idea to do that in any kind of service? What happens with an open file handle when the process gets killed?
Is there a preferred way to achieve this like using a foreground service?
I think I won't be the first person having this type of problem/question, but I could not find anything on Google or SO. Thanks in advance.
Android services might get killed by the operating system at any possible time.
More accurately, Android app processes might get killed by the operating system at any point.
There are no guaranteed lifecycle calls like onDestroy() you can rely on.
Correct. onDestroy() is very likely to be called, but it is not guaranteed.
I have to implement a service doing a lot of long running tasks and a bunch of file operations in the background.
Pretty much any piece of software bigger than "hello, world" fits that description.
Is it generally a good idea to do that in any kind of service?
You do not have much of an option. A service is what is helping to keep your process around when it no longer is in the foreground from a UI standpoint. If you do not use a service, your process lifetime will likely be on the order of minutes, maybe less. With a service, your process lifetime can be hours, though it depends a lot on the device (e.g., amount of system RAM) and user (e.g., how busy the user is and how many other apps want to do background work).
What happens with an open file handle when the process gets killed?
If you have tried writing stuff to the file at about the point of process termination, any bytes not yet handed over to the OS (e.g., buffered in Java) will not be in the file.
Is there a preferred way to achieve this
I have no idea what "this" is.
like using a foreground service?
There are three main patterns for using a foreground service:
Brief transactions. K9 Mail, for example, appears to use a foreground service while it is checking for new messages, but only during that short window.
User-controlled operations. This is the conventional use case for foreground services. Music players, for example, will usually implement a foreground service for the music playback.
"I am going to try to live forever" types of services. That's not especially practical, as foreground services do not live forever. Users also get irritated with foreground services where they do not understand what they are getting as trade-off for the system RAM/CPU consumption and the always-visible notification icon.
Whether any of these patterns fits your project is something you would need to determine for yourself.
My application is essentially a service that is started on boot (by a boot-completed receiver), and should periodically gather data, send it over the network, and go to sleep (probably using AlarmManager). It has no activities - no UI whatsoever.
Is there any reason to spawn an additional thread to perform the application logic?
if not, where should I perform the logic? in the OnStart method?
Is there any reason to spawn an additional thread to perform the application logic?
Absolutely. Your service will be killed off if it fails to respond within 5-10 seconds. Nothing can tie up the main application thread for that length of time.
I recommend an IntentService for use with AlarmManager. In particular, if you want the device to stay awake while you are doing whatever it is you are doing, you might consider my WakefulIntentService.
Also, regarding "no UI whatsoever", if you plan on distributing this app via the Android Market, please bear in mind that users seem to dislike applications with no UI. They install it, get confused when there is no icon in the launcher, and give you a one-star rating. Even if you do not need a UI for actual operation, you might consider at least having some activity in the launcher, that shows documentation, perhaps a log of work being done, allows adjustment to the frequency of your work, etc.