I'm using an IntentService to perform background tasks, such as updating data from a remote server.
In some cases, the same request can be queued multiple times by the user, but I only want to execute it once (there's no point in updating the data from the server twice in a row).
Is there a simple way to do this using an IntentService, or should I just use a standard Service?
Is there a simple way to do this using an IntentService
Unfortunately, no. The Handler queue used by the IntentService is not visible through the SDK and does not have public methods to let you inspect its contents, anyway.
should I just use a standard Service?
Probably. You could try to keep your own parallel copy of the work queue, flagging duplicates and ignoring them in your onHandleIntent(), but making sure you are always in sync with the real internal queue might get icky.
Related
I want to get data from the server and store it in a cache regularly, even when the app is closed. I am not sure what is the correct way to do it. I have listed down the possible ways I can think of. Please let me know the correct or the best way to do it. Really appreciate any help.
Create an Activity and set a repeated alarm to call a service. The service should connect to the server and download the data in cache.
From a fragment, check the last time the cache was updated and then if the data is out-dated, connect to server in a background thread and update the cache.
You can Directly Use IntentService for Frequently Updating Data
IntentService is a subclass of android.app.Service class. A stated intent service allows to handle long running tasks without effecting the application UI thread. This is not bound to any activity so, it is not getting effected for any change in activity lifecycle. Once IntentService is started, it handles each Intent using a worker thread and stops itself when it runs out of work.
IntentService would be an best solution, If you have an work queue to process. For example, if your application using analytics you will likely to send event name and related parameter to your tracking server for each user generated event. Although each event means a tiny piece of data, creating networking request on each click will result an overhead to your application
For implementation : Updating Data from Server Using Intent Serive
Do take a look at Android Sync Adapter Framework.
https://developer.android.com/training/sync-adapters/index.html
Hope this helps.
I am in the middle of developing an android application and I have stumbled across something that I don't really know the best way to solve.
What I wwant to achieve is, when a user logs into the application, I want to start a thread if the device is connected to a network(what kind of network doesn't matter)
The thread should perform an action every 10 minutes.
What this thread needs to do is, loop trough a list, a queue to be more exact.
This queue will have objects, and based on the objects in the queue when there is a connection available, execute.
The queue will be filled trough the flow of the application.
For example filling in a questionary.
The answers need to be synched to the server. Every question can include pictures takebn from the camera etc, so I want to save certain data as an object, put them in a queue, and have a thread handle the http requests. This way the UI won't be blocked. It's of great importance to sync whenever possible.
What I want to avoid is having another process run aside from my own APP. That's why I haven't used a service. Or do I missunderstand the concept of services as a whole?
Are there specific queue objects or lists?
I want to loop trough the queue list that can be filled at anytime while the program is alive, with a thread.sleep like method when the list is completely empty.
Please leave me hints and tips on what way to go with this.
A service isn't it's own process... from the Documentation: "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 really is the best choice for what you're talking about. You spawn your own thread in the service that then does the following: check your queue for objects and send any to the server (since you're already not on the UI thread, you can do this without spawning yet another thread if you want). If the queue is empty, use a Timer to schedule another invocation of your upload method.
Handler or Listeners. What is better use for notification of event? What is faster, more efficient etc.?
That's a good question!
scenario for using a handler
I've got an Android background service running in my app that uses handlers exclusively for web communications - I decided to go this route because the handler will queue requests and execute them one by one so then I know that a sequence is remained intact.
For example, in an instant messenger app you might find it desirable to maintain a sequence for your chatting.
scenario for using a callback
My background service also uses a class that reads from hardware (in a separate thread); some data might come in at any time and needs to be processed immediately. For that class I implemented a listener/callback interface.
My only question is whether there's any etiquette for the size of the handler.
I have about 50 unique messages:
outgoing web requests consists of about 25 messages (each message is a different API on the web server)
Each API returns a response, therefore there's another 25 incoming web
responses
The handler requires about 60% of the service's code - as you can imagine this results in a very big switch(case{}) structure (almost 1000 lines of code). Too big? How to break it apart?
There's no such thing as a Listener type, it's just a naming convention for callback interfaces. So you just use them if you want to process your events synchronously on the same thread.
A Handler is however an Android class... you use it for passing messages and runnables from the thread raising the event (e.g. "download complete") to the thread that needs to handle it (e.g. the UI thread).
is a good practice to have an Asynk task with a loop like this inside?
while (true) {
check queue and request API
Because i need to wait for my Activities and service needs to comunicate with the APi.
Thanks
I am assuming the "queue" is a Java queue, perhaps a LinkedBlockingQueue. If so, that queue is unnecessary, as AsyncTask has a queue to go along with its thread pool.
So, the question is: what triggers things to go in the queue?
If the trigger is a user event (e.g., menu choice, button push), just have it launch an AsyncTask, or have it have a Service launch an AsyncTask. That work will be queued up by the AsyncTask system.
If the trigger is the passage of time (e.g., we want to check an external server every 10 minutes), I would use AlarmManager and consider switching from AsyncTask and a Service to using an IntentService.
I have a priority queue in order to select first the important calls to the API.
My program have two services:
One calls the API when a message is added to the queue. The call to the api is made by an Asinc Task in this way:
messages.add(request);
new DownloadApiTask().execute();
The other service is updating the local database. For that, i have a loop in which i call the first service in order to get data from the API. The basic structure is:
while ihave data to updload
mFirstService.putMessage(request).
Fine, the problem is i have a rejected Execution Exception every X calls, I think it can be because i invoke the asinc task every time i take a message.
For that, i was thinking in force to the asinck task to check the queue instead executing it.
I hope you can understand my problem.
Thanks
Here's scenario:
Client makes remote call to the service (returns void) and provides
a callback object
Service executes some long running logic on the background thread
and then uses callback object to trigger ether success or failure
which (since these manipulate visual elements) execute in
Activity#runOnUiThread block
The scenario runs fine. The question is - can I use AsyncTask to make
code less verbose (how?) and would be there any advantages in doing it
that way?
Or should I just get away from client callbacks alltogether and
execute remote service calls retrofitted to return some value within
AsyncTask#doInBackground?
It is difficult to say whether AsyncTask will make things less verbose, since we don't know the verbosity of your current implementation.
For me, AsyncTask means I don't have to worry about cleaning up threads myself (e.g., post some sort of kill job to a LinkedBlockingQueue my background thread is waiting on). It also eliminates the custom Job classes I used to create for using with LinkedBlockingQueues. And, it simplifies a bit doing final work back on the UI thread.
In your case, with a remote service, the UI thread issue is less critical, since the activity needs to handle that itself.
I don't see what the difference is between your #2 and your last paragraph. In both cases, your service will call the callback object, which will use something like runOnUiThread() to arrange for the work to be done on the UI thread.
AFAIK, the only two ways to have a service doing any sort of asynchronous work let the client know that work is done is by a broadcast Intent or a callback object. Broadcast Intents are convenient but public (i.e., other code can watch for them).
I suspect I probably have not helped much here, but I just don't know enough of your scenario to provide greater detail.
I'm having quite the same question : i'm developping a map activity, with a 'lazy-loading' functionnality (xml from Network, parsing it, then updating my map with the 'items' created from that parsing...)
i wondered what would be 'the best' way to implement it...
async service launched from a thread, an update notification via Intent?
just a thread (no service, since i don't need to expose it to other applications) w/ callback
asyncTask with callback
i'm comparingthese in terms of speed, using the Android SDK performance analysis Tool traceview
I guess a more precise answer might be found from Android contributors on the Android-developper-group...