I love IntentService and try and use it whenever I have to write a Service.
However I have to perform a long task (~4 seconds) at least once, when the application starts. The task is to load a raw resource (a certificate) and use it for all web service calls. Currently I'm loading it each time a web service call is made, which is obviously not a real solution.
Because IntentService is stateless I can't keep the certificate around between requests. What are my options other than writing a "normal" Service and implementing the lifecycle carefully to check when the certificate should be (re)loaded.
Thanks.
The task is to load a raw resource (a certificate) and use it for all web service calls.
Loading a raw resource should take milliseconds. Use Traceview to figure out why it is taking ~4 seconds.
Currently I'm loading it each time a web service call is made, which is obviously not a real solution.
Loading a raw resource every time seems like a perfectly viable solution. It's not like you have another choice.
What are my options other than writing a "normal" Service and implementing the lifecycle carefully to check when the certificate should be (re)loaded.
That would be a really bad idea.
Users greatly dislike developers who keep services running when they shouldn't. Users attack apps like this with task killers and force-stops in Settings. Once that happens, on Android 3.1+, your app will never run again until the user starts up one of your activities.
Also, Android will terminate your everlasting service after a while, once again to protect users from poorly-written services.
Focus instead on optimizing the ~4 second operation.
Related
Basically, there is a Google way, which suggests using Service for long running operations (which I use at the time). On the other hand, there are a lot of examples in community by honored developers, which avoid using Service and at most incorporate Fragment's setRetainInstance(boolean retain).
While Google has declared that a lot of bad stuff might happen if we don't use a Service, I still feel anxious because there are, it seems, so many projects leaving Service aside.
Can you consolidate the Google's case or provide suggestions for abandoning Service?
P.S. I'm developing "classic" rest-client applications.
P.S.S. I forgot to mention that Service is used in pair with ContentProvider(for cachging purposes, guard against system app forceshutdowns).
Thanks.
If the network request is very likely to take under a second, or if you don't mind it if your process terminates before the request completes, using simple threading from the UI layer is fine, IMHO.
But once the user leaves your app (HOME, responds to an incoming call, etc.), the lifetime of your process is limited, and it could be very short if you do not have a service to tell the OS that you're still doing important work for the user.
So, if the network request is more in the 1-15 second range, and you'd like to feel fairly confident that the work will run to completion, use an IntentService or something along those lines.
If the network request is likely to be longer than that, such as a large download, now you have to worry about the device going to sleep and such. My WakefulIntentService was designed for this sort of scenario, where it will keep the device awake long enough to get the work done, then let the device go back asleep.
Some developers use services for all significant network I/O, skipping them only for truly ephemeral stuff like thumbnail images to populate a ListView or RecyclerView. So long as the service is only running when it is actively delivering value to the user, this is perfectly fine.
In my app, I'm using a contact sync adapter, but it has a lot of information that it shares with the main app. There are settings that the adapter needs to work proplery (like login information and if the user changes any sync settings), so I currently have it running in the same process, and it communicates with the main ap using getApplicationContext(), and then I have some shared variables in the Application that the sync adapter is using during the sync process.
But in the training document, and a few tutorials online, the sample adapter is set up to run in its own process -- it's using android:process=":sync" in the manifest. Is that necessary? And if it does run in a separate process, how can I communicate back to the main app?
In our context, due to fast searching requirement, we are using remote service to hold a huge database in memory.
The reason we are using remote service, instead of local service is that, we believe running the service in separate process, will make us harder to hit maximum memory per process limitation (The limitation is vary based on different devices and OS version).
In our initial design, we are using AIDL. Later, we switch to Messenger. I cannot recall the reason behind. I will check back our source code history log to figure out why. But, I think it is mostly, Messenger is less complicated than AIDL, and we do not need the multi-thread capability provided by AIDL.
Running Service in its own process may be helpful
1) if you want your service to withstand your main app's process destruction (but START_STICKY is more than enough for that case),
2) if you'd like to designate this process for all "sync" tasks of your application (as stated in the tutorial),
3) if you want other apps to use your Service.
To communicate with the Service running in separate process, you use Bound Services.
However, running Service in separate process increases the complexity of communicating with it, so consider if any of cases mentioned above relates to your app purposes.
I think it should be separated, but it's not required.
In general, separating a Service process is well worth to consider if it may be used independently from system components or other applications. In this perspective, the lifecycle of the process should be managed independently from other components such as Activity in the same app, so Android can mark which process is currently used easily and precisely to decide which process to be killed in case of a memory shortage. Also the service can keep running even if the front activity crashed unexpectedly.
It's hard to maintain sharing data between separate processes. For login credentials and preferences, I guess you may go with a combination of SharedPreferences and OnSharedPreferenceChangeListener.
When the application starts, it may cache different things, in particular for the UI. By splitting the sync logic in a different process, you allow the UI process to be killed when the device is running low in memory, which will free these UI caches.
Hence, this technique is primarily of interest to apps that run services for a long time. Typical examples:
the service that plays music in a music app
the service that uploads the video in Youtube
However:
this increases the complexity of the app
if done incorrectly, it can actually increase the overall memory footprint of the app
I have been developing for Android for little less then 2 years, and I am still puzzled by this seemingly simple question.
When should one implement a service?
From my experience there are some rare cases but I am questioning this because on every phone there are quite a lot of them running and I doubt it's just a poor application design.
This is essentially core of my question but following are some of my experiences and thoughts about the subject which can explain my question in more detail.
In all apps that I have developed only one really required a service. It was a background sound recorder and I was using it as Foreground service with notification since I wanted buttons to be able to control it (like music players do for example).
Except this I never really saw a requirement for the constantly running service because:
A) Intent listeners (Manifest registered BroadcastReceivers) are quite a useful feature and using them as you know is usually enough for many use-cases (for example showing notifications).
B) If scheduled execution is a must one can subscribe to alarm events.
C) I know that service in Android is quite different then for example in Windows since in Android services are just a "package" to organize your code in and have a the system manage the lifetime of the object. Services use the Main Thread but it's customary to spawn new threads in them.
D) In the development documentation services are suggested for network communication and background calculations but I don't get why you should not just use AsyncTasks for that. I am a big fan of these and use them extensively for lot of things from downloading data from the internet to doing FFT calculations under time critical conditions.
E) I get the usefulness of Foreground services but why are people using background services so much (excluding the system apps).
Those are my thoughts about the SERVICE and I hope someone with more experience will be able to explain these PROS and CONS (along with others that I probably missed).
When should one implement a service?
When you have work -- delivering value to the user -- that:
Needs some time to complete, perhaps longer than you have time for in the component wishing the work to be done, or
Is delivering that value under user control (e.g., music player, controlled by play/pause buttons in a UI), or
In rare cases, needs to be running continuously, as it delivers value continuously
there are quite a lot of them running and I doubt it's just a poor application design
Some are likely to be poor implementations, either due to technical misunderstandings, or other concerns (e.g., making marketing happy) trumping making users happy.
It was a background sound recorder and I was using it as Foreground service with notification since I wanted buttons to be able to control it (like music players do for example)
That is a reasonable use for a service, IMHO.
Intent listeners are quite a useful feature and using them as you know is usually enough for many use-cases (for example showing notifications)
I assume that by "Intent listeners" you mean manifest-registered BroadcastReceivers. In that case, if the work to be done by the BroadcastReceiver will take more than a millisecond, that work should be delegated to an IntentService for completion. onReceive() is called on the main application thread, and it is not safe for a manifest-registered BroadcastReceiver to fork a bare thread, as the process could go away shortly after onReceive() returns. However, in these cases, the service is usually short-lived (e.g., do some network I/O and disk I/O, then go away).
In the development documentation services are suggested for network communication and background calculations but I don't get why you should not just use AsyncTasks for that
An AsyncTask is a fine solution for background work that is:
Requested by the UI (activity or fragment), and
Will take less than a second or so, and
Is non-critical
For example, if you are downloading avatars to show in a ListView, AsyncTask is probably a fine choice, whether you use them directly or use some image-fetching library that uses them internally.
Conversely, if the user buys an MP3 through your app, and you need to download that MP3 file, an AsyncTask is not a good solution. That could easily take over a second. While the download is going on, the user could switch away from the app (e.g., press HOME). At that point, your process is eligible to be terminated... perhaps before your download is complete. Using an IntentService to manage the download is a signal to the OS that you are really doing work here, adding value to the user, and so the process will be left alone for a little while.
Note that if the background work might take 15+ seconds, WakefulBroadcastReceiver or my WakefulIntentService is probably a good idea, so the device does not fall asleep while you are trying to wrap up this bit of work.
I can name some of the Service uses from my experience:
to implement
location listener,
sound module, generating various voices
in app content updates,
API, provide services to other apps
in app billing
Communication with webservices (if requests frequency is high)
actually (excluding 5.) they all are working for the whole app duration, they are using some of the other android services, also they manage their state. I suppose one of the important thing here is state management during application life cycle changes.
I prefer to look at AsyncTasks in a same way as Executors (ExecutorService), they should be executed sequentially and for small tasks.
In the android website, you can find a table when to use Service, Thread, or WorkManager (the new API for scheduling jobs, currently in alpha as of this comment posted). https://developer.android.com/guide/background/#table-choose
The website also state that you need to use started service only as last resort. The Android platform may not support started services in the future. Refer to this link https://developer.android.com/topic/performance/scheduling#services
You should avoid using started services that run perpetually or perform periodic work, since they continue to use device resources even when they aren't performing useful tasks. Instead, you should use other solutions that this page describes, and that provide native lifecycle management. Use started services only as a last resort. The Android platform may not support started services in the future.
If you consider UI and bound services, u would think that both can exist and not be doing anything for certian periods. In such scenarios, your UI can be recreated a lot of times however service does not. And this is where service is important. Lets say you are processing images and then rotate device you want processing to continue while UI is being recreated. You recording a voice and then rotate device. These are one of the places where I find service very important. (Having lot of heavy data processing, interaction with web, that could be few seconds)
I was reading a article in Android developer blog Process and Threads which talks about creating new process for specific component of Application. But I failed to understand when will creating a new process in my application becomes a absolute need. Could you please help me understand following doubts I have in this regard.
When as a developer I should feel I need to have a separate process for a Android component/s?
Does introducing a new process has any side effect on application's overall performance?
Any other info is greatly appreciated.
Thanks,
SKU
Having a separate process can be useful if there are components of your application that do not necessarily need to both be running to be useful to the user, and the background task is critical to application "correctness" (either now or in the future). The classic example of this is an app that has a service where the service saves or uploads some data that is critical to your application (critical meaning the only way to get the data back is to have the user re-enter it!). The service might be responsible for doing something like uploading or saving data, while the activity is just the interface for the user. So developers should decouple these two components to prevent problems that may arise from my next point..
Android was designed to run in a resource (especially memory) constrained environment, so processes deemed unimportant are killed periodically to open up memory for important ones by the "low memory killer" (LMK) (if you Google this you'll get tons of information on the topic). Things like foreground processes are understandably given a higher priority since they're currently in use, but they're sometimes killed off as well for reasons like consuming too much memory. Now, imagine you need to save off some data to a database after the user does something in the app and you use a service to do so to ensure that it is done even if the user navigates away from the app. Unless you create the service in its own process the process containing both the activity and the service is likely to be killed since the process belongs to a non-foreground activity.
However it is not always necessary to place the service in its own process, oftentimes simply giving the service its own thread will suffice; it's very application specific. I would only place a service in its own process if it took longer than maybe a few seconds (long enough for the user to navigate away from my application and for the LMK to step in) to perform some task in the background and that task related to the "correctness" of my application (I.E. saving data for later). For something like caching, stick to threads, since if the process gets prematurely killed you can just recreate that data later.
Another reason to have a separate process is if you're running a global service (a service that can be used by applications other than your own) that maybe you provide an interface with via an Activity for configuration.
As for the performance question, there will definitely be a performance hit for something like this. Interprocess communication is not cheap, so you should really only use a separate process if you fit into a specific use case, like the ones mentioned above. Also, there's a certain amount of memory overhead for maintaining a process, so that's another performance hit.
1.)You need to do something on seperate process or thread when you don't want your app to behave slowly. As by introducing threads you force your app not to run on UI thread. Thus making your app responsive to other events. For Example : you can use threads when you have to fetch some data from web service so that it happens in background and doesn't effect your app.
2.)Threads should not be used..We should use AsyncTask or loaders rather in android.
1.) In android 4.0 (and possibly 3.0, not sure though) The device does not let you use the HTTP Agent in the main thread, for this slows the UI..
This is when threads come in handy.
Also with the use of functions that need alot of cpu, if these are run in the UI thread, the UI will lag and not respond until the function finishes.
2.) as stated at 1, it will actually improve the visual performance of your app ;)
I have a task which I need to run in the background in my Android app. It reads data over the network and populates a database. It can take several minutes to run.
Once it's started, it needs to complete successfully without interruption. (Otherwise I'll end up with a broken half-populated database.) I realise I can never guarantee it will always complete, but I want to make it as hard as possible for the system to kill off this task. For safety I guess I will have it populate a temporary database, and then only swap out the old database for the new one on successful completion of the import.
It's a modal operation; it does not make sense for the user to be interacting with the app while the import is in progress.
My first attempt is using an ASyncTask with a Progress dialog to achieve the modality, but this obviously breaks the "don't interrupt" requirement. I could work around the screen-rotation issue with ASyncTasks, but I don't think that goes far enough.
At the moment I'm not sure if this should be an ASyncTask, a Service, an IntentService, some combination of these, or something else entirely. Can you help me decide?
I'd run it as a service and additionally I'd also have a clean SQLite DB on my server populated with the data the clients are going to retrieve so I can generate a kind of signature. Have the clients check for the correct signature of the DB. If the signature is not matching the servers signature then reinitialize the database filling process.
This is just an idea tho. I have no idea whether it'd be possible with what you are trying to do or not.
You are better off with services in that case. The Android runtime will leave it alone working as long as enough memory is available. In the case it kills the service, you can save the state in a bundle, and the system will restart the process as soon as possible, so you can resume the process, if possible for your solution:
Android Fundamentals, Service Section
Then it is easy to communicate with the service, like showing the progress/ notifications etc, using a handle registry like proposes by Mark Bredy in his Android Service Prototype