Pattern for multiple Loaders with LoaderManager? - android

I'm using Fragments and LoaderManager. I have to launch an unknown number of tasks, and they might be run in parallel (otherwise I'd just reuse one and only one loader). For example, I have a listview, and each row might have a button to save the content of that row to a webserver. The user could initiate a save request on multiple items in parallel.
private int nextId = 0;
private void onClickListener() {
Bundle bundle = new Bundle();
bundle.putNextData(...);
getLoaderManager().initLoader(nextId++, bundle, this);
}
I could try bookkeeping myself, so create a pool of loaders manually and reuse them when possible, seems like it might be something already implemented by the API?
Thanks

I don't think you should use a Loader for saving data to a remote server.
Instead, use an IntentService or something similar to process a queue of "save" operations. This way, your communication with the web server can be batched, collapsed (i.e. multiple queued saves for a single item can be collapsed into one operation), and will live beyond the lifespan of your activity if need be.
A save queue processed by an IntentService (or equivalent) is also a great way to retry failed operations with backoff, since you can implement delayed retries with exponential backoff using AlarmManager.

An IntentService or bound service are always good approaches for that.
As Roman points, note that enqueuing several requests and called them separately is not highly recommended (it is very likely that you give a lot of work to the radio connection - when using data - which among other things drain your battery. Here is must-read about that)
I'd personally recommend to use a bound service with a queue of requests and a pool of threads available (that approach gives you full control for more complex network operations like in your case). There are more details on the approach here and a testcase working example over here.
Update us about your progress.

You are at the right direction, let me just help you a bit.
Reusing is indeed a good idea, and you do not have to worry about it because Android did it for you(Or Java actually ;)
It called ThreadPoolExecuter, you can start as many tasks as you wish and he will only open the predefined number of threads.(Best practice is trying to open as many threads as parallel network connection can be run on the device. From my research it is between 4 - 9).
And if you are trying to download same URL twice may be you can protect your self and open only one task for it.

Related

What is the best practice for a multiple request at same time

I have to send four different request in an api at the same time. Do i need to make AsyncTask background thread for each request or all request could be done through a single AsyncTask. Can somebody please help.
This is a concurrency issue. There is literally dozens of ways to do this in Android. I've written almost every single one for courses that cover this material... and even then it isn't 'simple'.
I'd personally make use of HaMeR (Handler, Messages, Runnable) framework of Android. Create 4 runnables and have them post their results to a Handler.
However... That isn't the easiest to implement. and would require you to understand how to safely create your own custom handler (making use of WeakReference properly, etc.)
Therefore, I'd recommend running the asyncTask(s) on the executorService
myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); The default thread pool executor should start with 4 threads (I believe off-hand without looking it up).
I am assuming you are using HttpURLConnections. Unfortunately each of those connections, as specified in the documentation, is capable of handling only a single request.
However, you can (and possibly should) still perform all your requests in a single AsyncTask. Each AsyncTask will require the creation of a new thread which takes lots of time and resources. So don't listen to anyone who tells you to create a new task for each request.
You also have the option of exploiting HTTP persistence. If you add the header Connection: Keep-Alive to your request via connection.setRequestProperty("Connection", "Keep-Alive");, you will be able to send multiple requests over the same connection and save a lot of time and resources.
It's a little complicated in Java, because of the one-request-per-httpurlconnection rule, but it can be done. First, when you are done with your first request's HttpURLConnection do not close that connection. Then, to create the next connection, call url.openConnection() on the same URL object that you used to create your first HttpURLConnection. The JVM will know to reuse that connection if possible to save bandwidth.
You also have the option of using HTTP/2.0 multiplexing, which allows you to send multiple requests literally at the same time. Unfortunately I am not yet well versed enough in HTTP/2.0 to tell you exactly how to make use of this, but the multiplexing feature was included to solve exactly this problem.

Performing Request After Android Service Binding

I have a two part question. Both are somewhat general.
I'm creating an app that relies heavily on communication with a server. I plan to have different classes for each repository I'll need. Is an Android service the correct pattern to use here? There may be certain situations where I'll want to cache things between activities. Will a service allow me to do this?
Assuming a service is what I want to use for this, how can I load content once the service is bound. When the user opens the app, I want to start loading content. However, binding a service isn't blocking, so I can't write the code that makes requests with the service in my onStart() right? Is there some helper class that will wait for the service to load then execute a function? I know I could put some code in my onServiceConnected() method but I'd like to stay away from coupling like that.
Hopefully that wasn't too abstract. Thanks in advance.
Yes, Service is the way to go, but a started service, not a bound one.
You could make async request methods, and the Service can broadcast the result back to your Activity.
The async request in this case is a startService(intent) with an
Intent containing the request parameters. The service would start a background thread for the operation, optimally you can use a networking library for this (for example Volley).
And the reply is a broadcast by the Service with the relevant data.
This answers the problem of caching, because the Service can decide what to return. So in case the Service does not have the requested resource, it will download (and return) it. But if the Service has the resource, then it will just simply return the cached version.
To start, you should get yourself familiar with these topics:
Started Services (for the requests)
LocalBroadcastReceiver (for the reply)
Event Bus (alternative to LocalBroadcastReceiver, for example Otto)
I don't know much about your concrete needs, but it seems like you want to implement a REST client with cache. There is a really good Google IO presentation on that here. Definately worth to watch!
1)If you need code to run even when your Activity isn't, the correct answer is a Service. If you just need to cache data, then storing it in a global static variable somewhere may be ok.
2)Your service can start a Thread or AsyncTask. These execute in parallel. onStartCommand generally launches it in this case.
As with most things, the answer to these questions are subjective at best. I would need more information then I currently have, but I'll take a vague, general stab at this...
If you need something persistently hitting your server repeatedly I would say use a service.
Where you call it is not nearly as important as how many times it needs to be called. That being said the answer is yes. If you need this data as soon as the application or activity loads, then the onCreate method is where it needs to be loaded.
My reccomendation is either A) service or B)AsyncTask.
Go with A if you have to hit the server repeatedly for data and need it in regular intervals. Otherwise go with an AsyncTask and load all the data you need into an object for storage. Then you can use it as you need and it will essentially be "cached".
The difference between the two is simply "best tool for the job". I see you use some javascript. To give a proper analogy, using a service for a server call rather than an async task, is the equivalent of using a web socket (node js) when you could of just used an ajax call. Hope this helps. Oh and PS, please don't use static variables in Android =).

Best practice to handle orientation change: Android

I was going through various practices to handle orientation change with threads and AsyncTask. I came across following solutions:
Attach-detach model : Attaching and detaching activity to threads and AsyncTask while preserving their instance. (Source: 1, 2)
Headless fragment way : Using a non-UI/headless fragment to do all the thread related operations and retaining its instance on configuration change. (Source: 1, 2)
Are there any other approaches to handle this scenario? What is the recommended practice? I'm asking this because I couldn't find a generic solution anywhere in the Android docs.
Some summaries
There are several methods mentioned above that are good practices but I thought I might sum them up with short explanations. Below are some of the most popular libraries being used currently for http networking, asynchronous work / threading, and caching.
My current project (just preferences)
I personally am currently using Otto, Loaders, Volley, Ormlite, and a network stack based on Apache and Services. I do hope to replace, the network stack at some point with either Volley, Retrofit, and maybe eventually Robospice.
I personally very much like Otto and Volley
RoboSpice (Modular)
https://github.com/octo-online/robospice
http://www.youtube.com/watch?v=ONaD1mB8r-A
a plugin / modular approach to long-running tasks
this is like the "swiss-army-knife" of libraries, but you need to know what each tool does.
Handles REST calls
persists data through orientation and other changes
can handle disk and memory caching )
works with various HTTP libraries and persistence libraries (Gson, Jackson, Spring, OkHttp, and many of the below libraries)
beta for Ormlite support, I think
Retrofit (REST)
https://github.com/square/retrofit
Annotation library to make REST very easy. Works with Robospice.
Volley (Networking data & Images)
https://android.googlesource.com/platform/frameworks/volley
https://developers.google.com/events/io/sessions/325304728
This is the networking code that runs the Google Play Store
Fast, reliable
Handles most caching for you with some sensible defaults
very easy to use
built specifically for very fast image, json, etc loading
Handles all threading for you.
Picasso (images)
https://github.com/square/picasso
Http library for loading images
fast
very easy to use
Loaders (Android)
well supported
persist through orientation change and save/load of fragment state
can be difficult to get right
no caching
AsyncTask (Android)
simple way for background work from the UI thread
must be canceled and be careful about tasks that return after an activity or fragment is torn down.
Otto (event bus)
https://github.com/square/otto
Event bus that makes a-sync work between components and fragments easy
Very powerful #Produce ability retains the last event and can produce it on demand for any new interested subscribers to the bus
Headless Fragments (?)
I personally have never seen this used other than Vogella's tutorials, so I'm not sure on this one.
Service (Android)
The old school way
ultimate control, you must do everything yourself
usually used with Appache or HURL client and
pass Parcels around via Intents
Why don't you try Loaders, in particular AsyncTaskLoader? They are available for pre-Honeycomb through Support Library and perfectly match Activity/Fragment lifecycle. Here is the official summary:
They are available to every Activity and Fragment.
They provide asynchronous loading of data.
They monitor the source of their data and deliver new results when the content changes.
They automatically reconnect to the last loader's cursor when being recreated after a configuration change. Thus, they don't need to re-query their data.
We are actually using RoboSpice library. It runs on a Service with only providing RequestListeners objects.
The problem with your first approach (Keeping references between the AsyncTask) is that you can probably generate memory leaks because when your AsyncTasks holds your Activities references, they will be not garbage collected. Keep an eye on this just profiling your application checking Heap Size rotating the same Activity over and over again. Your heap should grow in the normal parameters (There is a moment when your objects that must be garbage collected lives at the same time with new objects) but when GC runs your RAM allocation should fall to the same size that you've allocated at the beginning.
So if I have to recommend something will be the next thing:
Activity managing API Calls and Flows (With RoboSpice, letting de UI rotate)
Simple screens inside Fragments using retainInstance in true. This let to you pass your DTOs directly to your fragments, and you have to only manage the state at the top level Activity.
If handling asyncTask is your main concern i.e not willing to download data each time orientation is changed then you may try like this --
(1) Initialize any value before on create like this ..
Boolean android_hacker = false;
(2) Now when you are done with downloading data on AsyncTask class then set that value to true
android_hacker = true;
Here maintain all data utilizing model and Array adapter class
(3) Now each time orientation is changed then check like this
if( android_hacker = true ){
// Use your saved instance ..
}else{
// Download data as it is yet not downloaded ..
}
Hope it helps ..
There are many ways you can try beside the AsyncTask. And if you try to find a best practice, AsyncTask isn't a good option. This answer explains why you should not use AsyncTask. And they recommend you using a better way which can deal with long running task, RoboSpice. I have already used this library and I think it is worthy to try: respect activities lifecycles (orientation change), no memory leaks, supports multi-threading, caches results... It can plug and unplug long request task by using cache (but it can't work well for a non-cache request).
But I recommend a good way comes from Google: IntentService and BroadcastReceiver. You will registered and unregistered broadcast during orientation change to receive the data result. All background task will work in IntentService and notify whatever you want to activity by BroadcastReceiver. There are a lots of example that you can try. Something like this: http://mobile.tutsplus.com/tutorials/android/android-fundamentals-intentservice-basics/
Update:
Hi R4j, the point is my application is quiet complex. And I've to make
number of parallel network calls. Your approach with IntentService is
good but isn't suitable for complex scenarios
I don't think this is a problem. You can do anything with the IntentService, even the complicated tasks. If you want parallel tasks, you may consider a Service with multithreading in it and communicate with activity by Intent. Sending intent between Service and activity is safe and flexible, that is Android way.
And if you want to cache (by file download, stream, by database..) RoboSpice is a best choice for you
You can try with the following approaches:
1) If your application does not explicitly require any orientation changes, just disable orientation changes at the beginning of app execution, thereby you would be avoiding any crashes or related problems with respect to orientation changes.
This you can do using the following line in the outermost layout of your layout xml file:
android:orientation="vertical"
(for setting vertical orientation)
2) You can set or preserve previous orientation values at the beginning of your thread execution using Asynctask, as follows (syntax example only):
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
and
getResources().getConfiguration().orientation

When to use Android Loaders

Loaders
monitor data source and deliver new results
After a configuration change : no need to re-query the data
I read the android guide about Loaders.
I read Alex Lockwood 4 parts tutorial . Tested his sample app too.
Tried to read the Google App for I/O 13, there's a Stream feature and reading its code find out it uses Loaders since it provides code to create a StreamLoader. Here is the Link
I suppose they use it to monitor for new data and add them to their view.
Same for Alex's app. There's an observer and when there is new data entries triggers a refresh for the UI.
So far it seems to me, Loaders are ideal choice for a "livescore" app. When there's a new update ( which means a new data entry ) it appears on your screen.
Maybe something like Twitter. New messages for you, custom Observer to notice for changes, custom Loader brings the data and an adapter to display them. No need to "pull-to-refresh".
But then again Twitter has its own RESTful API which kinda does the same job. No need for a pointer to the new data. ( don't know how they do it but I guess somehow the "push" new data to your device ).
So my question is :
Loaders are best option when we want to observe a data source and change our view so it will display the new data?
Are there any examples/app I can check dealing with that logic : monitor the data source -> get the data -> refresh UI
Any characteristic cases ( like the one with the "livescore" previously mentioned by me ) that when we have to deal with them we have to choose Loaders?
The second part of the Loaders ( configuration change, keeping the data ) I think its clear. No one want's to re-download an Image gallery when the user rotates the device.
Thank you and excuse my confusion
The best way I can describe a Loader is a Handler that is always on. Both Loaders and Handlers pass data between objects.
I agree with what you said about the "livescore" app.
The Loader monitors the source of their data and delivers new results when the content changes.
To answer your questions:
1) Loaders are best option when we want to observe a data source and change our view so it will display the new data?
A: Yes. if your data source is constantly updating. For example, like a stock-ticker app. If your data isn't constantly updating, then no, don't use a loader. For example, if your data source is only retrieved once, then there's no need for a Loader.
2) Are there any examples/app I can check dealing with that logic : monitor the data source -> get the data -> refresh UI
A: https://www.youtube.com/watch?v=3d9BeWqlfTk
Yes, they are what you want to use for the flow you're describing. Tangentially, there's also AsyncTasks and Services that have similarities.
AsyncTasks
Description (from docs):
AsyncTask is designed to be a helper class around Thread and Handler and does not constitute a generic threading framework. AsyncTasks should ideally be used for short operations (a few seconds at the most.)
Caution: Another problem you might encounter when using a worker thread is unexpected restarts in your activity due to a runtime configuration change (such as when the user changes the screen orientation), which may destroy your worker thread. To see how you can persist your task during one of these restarts and how to properly cancel the task when the activity is destroyed, see the source code for the Shelves sample application.
If you specifically just want a wrapper to basic threading boilerplate, use an AsyncTask otherwise I'd suggest you use an AsyncTaskLoader if you need a general purpose way to run intensive operations in an Activity or Fragment. You get the same benefits from AsyncTask, but it handles lifecycle issues for you. There are also specialty loaders, such as CursorLoader that will are made to handle specific data sources and have conveniences for interacting with certain UI elements.
Services
Description (from docs):
A Service is an application component that can perform long-running operations in the background and does not provide a user interface. Another application component can start a service and it will continue to run in the background even if the user switches to another application. Additionally, a component can bind to a service to interact with it and even perform interprocess communication (IPC). For example, a service might handle network transactions, play music, perform file I/O, or interact with a content provider, all from the background.
You would use a service to handle data being pushed to a phone. Otherwise, the user would have to open your app to get any pushed data. Services do not interact with your UI. So a common design pattern is to use a Service to gather data from a server (whether pushed real time or if you poll) and store it in your database for use both when your app is opened or when not. There are many other use cases for Services, but this one is probably the most popular.
Conclusion
So no, you aren't required to use a Loader to load data or do long running operations on a background thread and pass the results (or progress) to your UI thread, but they are the best option for most use cases.

Android Async Data Loading Methods

If I need to asynchronously load some data via HTTP (or whatever) in order to update the UI, I have a few options when writing an Android application (among many others that I'm sure I missed):
Use a regular thread and a handler to update the UI.
AsyncTask
Use and IntentService, and use either a callback or broadcast the results via an Intent.
Using Loaders.
From what I understand, an IntentService is not tied to an Activity's lifecycle, so any changes to orientation, etc, will not impact the retrieval of data. Where this is not the case for an AsyncTask or thread fired off within an Activity.
The reason for the question, is that I just recently read about Loaders, and am confused as to their application. They seem to be more closely tied to a data source, where if the data source changes, then "transparently" everything is handled appropriately. Loaders also appear to be tolerant to configuration/orientation changes (I believe).
I've been currently using an IntentService to make RESTful service calls, and broadcasting the results to be received by appropriate Activities.
I'm assuming I could write an HTTP based Loader, but I'm not sure if this is the best use of this mechanism.
What are the advantages/disadvantages to using one of the async data loading methods over any other?
All of these mechanisms are simply options. There's no such thing as a one size fits all tool and so all of these different methods of completing the same task is a way to cover as many use cases as possible.
Ultimately, it's up to you to decide which method makes more sense for your scenario. But for a sort of generic explanation of what you should use...
Regular thread and a handler - Why when there are other, simpler, options?
AsyncTask - Since an AsyncTask will almost always depend on an Activity, use this when you need to load data asynchronously and you are 100% certain of how long it may take. Example: Executing an SQLite query.
IntentService/Service - Services are not bound to an Activity like an AsyncTask is, therefore, they are perfect for scenarios in which you may not know how long it will take to complete. Example: Downloading data from a web API and updating a database.
Loaders - Loaders are aimed at simplifying the process of loading data and populating it into UI. The nature of Loaders sort of assumes that the data you will be loading will be presented to the user as a list of some sort. Example: Downloading data and populating it into a ListView

Categories

Resources