In an Android app, I have to make multiple GET requests to a URL in order to transmit data to an external server (that's how the third party API works).
Data comes in sporadically. I store this data in a queue and want to send it to the server in a background asynchronously without slowing down the main UI thread. Each unit of data in the queue requires a GET request. The queue has to be emptied even if the app closes.
What's the best practice to do this? Please post/direct me to code/tutorials.
What's the best practice to do this?
That would depend on what "this" is and where this work is being done.
If "this" is "asynchronous work", you will use threads in one form or fashion:
If your HTTP operations are driving a UI, you might use AsyncTask, so you can update the UI safely from onPostExecute()
If your HTTP operations are purely in the background, and you want to do one at a time, use an IntentService, which has its own background thread and work queue
If your HTTP operations are purely in the background, and you want to do one at at time, and you are concerned about ensuring that the device should stay awake while all this is going on, consider my WakefulIntentService
If your HTTP operations are purely in the background, but you feel that you want to do several at a time, roll your own Service that uses an Executor with your own thread pool, making sure that you shut down that service when the work is done (as IntentService does), and making sure that the device stays awake with a WakeLock (and perhaps a WifiLock)
Etc.
If "this" is "HTTP GET" requests, use:
HttpUrlConnection, or
HttpClient, or
OkHttp (wrapper around those with added benefits), or
Retrofit (if your GET requests are really Web service calls), or
Volley (if you like your HTTP wrapper code to be undocumented, unsupported, but Googly)
Any number of other third-party wrapper libraries
If "this" is "queue", use the Queue class, or LinkedBlockingQueue if you plan on having multiple threads work with it at once.
If "this" is something else, I can't help you, as I'm tired of guessing.
You could do your own async HTTP GET calls using AsyncTask but I would recommend against it unless you're doing it from a learning point of view. If you want a nice, clean and stable solution I'd suggest that you use the well known Android Asynchronous Http Client 3rd party library. From the site:
"An asynchronous callback-based Http client for Android built on top of Apache’s HttpClient libraries. All requests are made outside of your app’s main UI thread, but any callback logic will be executed on the same thread as the callback was created using Android’s Handler message passing."
Making a GET is as easy as:
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
System.out.println(response);
}
});
Related
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.
I am using the Retrofit 2 library for an android REST client. Retrofit itself supports synchronous and asynchronous request (cf. here), the reason for the latter being not to block a thread and thus not to get interrupted by android.
In practice, is it better to use synchronous calls in a native AsyncTask or asynchronous calls directly from Retrofit?
If one is preferable over the other, what are the technical reasons?
One of the main reasons to use any of the popular REST clients (retrofit, volley, etc) is that they reduce the amount of details you have manage at the application layer. One of those details is making sure your network requests happen off the main thread. Why would one use an AsyncTask when a library they are already using for other features provides the same functionality with less ceremony? The only reason I can think of is -- you don't think the library's threading is very good. That concern does not apply to retrofit 2, it uses OkHttp to dispatch async calls. OkHttp has been around awhile and used extensively, it manages its own thread pool to execute async requests, and is solid.
So, the upside to using retrofit async is cleaner code, and no downside I know of vs AsyncTask with retrofit sync calls. The only time I use the sync calls is when my code is already executing in a background thread for another reason. I never create a separate thread or asynctask just for the network call and use enqueue instead.
OKHttp supports both synchronous and asynchronous api.
If I want to issue an async request, I can:
Use a AsyncTask, and issue OKhttp synchronous api.
Issue a OKhttp asynchronous api.
What is the difference between these 2 options? And which one is better?
Quite a lot differs!
Using AsyncTask for HTTP requests is pretty much one of the worst things you can do on Android. It's fraught with problems and gotchas that are best unconditionally avoided. For example, you cannot cancel a request during execution. The patterns of using AsyncTask also commonly leak a reference to an Activity, a cardinal sin of Android development.
OkHttp's async is vastly superior for many reasons:
It supports native canceling. If a request is in-flight, the reference to the Callback is freed and will never be called. Additionally, if the request has not started yet it never will be executed. If you are using HTTP/2 or SPDY we can actually cancel mid-request saving bandwidth and power.
It supports tagging multiple requests and canceling them all with a single method call. This means every request you make in, say, an Activity can be tagged with the Activity instance. Then in onPause or onStop you can cancel all requests tagged with the Activity instance.
If you are using HTTP/2 or SPDY requests and responses are multiplexed over a single connection to the remote server and by using the asynchronous Call mechanism this is much more efficient than the blocking version.
So if you can, use Call.enqueue!
Nothing much. OKHttp async is OKHttp API driven. So as long as you bundle the jars together for all platforms you should be good. AsyncTask is Android way of doing things.
However since Honeycomb Async task runs the tasks sequentially and not in parallel. This means that though the execute method of AsyncTask spans a new thread which runs your job away from the UI thread but all the tasks sent to one AsyncTask run in the same spanned thread.
So for 3 tasks submitted u don't get 3 threads they all run sequentially on a single spanned thread. With OKHttp you can achieve true parallelism using callbacks and async GET and POST.
Though you can do true parallelism in AsyncTask methods as well (check the overloaded execute methods in AsyncTask) but default Android behavior is not to do so.
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.
I'm building this client for a web service.
Pretty much everything makes requests to a server and now what I do is, I open a new thread and put all my requests in the same thread. That means I'm making all my requests in a serial way inside the thread and that turns into a lot of waiting for the user. Aiming to make the application faster, I want to make every server request in an asynchronous way.
I have a Networking class that handles all the HTTP requests I need and I'm thinking of making it so that every request starts its own thread.
I'm thinking of using ASyncTask for this but I noticed that with ASyncTask I'd need a class for each of my http requests (a class for GET, POST, PUT, etc). Is that the best way of doing it? is there a more efficient/clean way of doing this? What do you guys suggest.
Seems like a design decision that will depend on exactly what you are up to. There are various ways in Android to execute tasks depending on whether the user is waiting for some data or is being notified later on once the background task completes.
I would suggest you to look at this post that compares various task mechanisms in Android. Apart from this also go through the java.util.concurrent package.
I'm sorry this is not a concrete answer, but take it from me - it mostly depends on how are you trying to serve the user. So one can only suggest ideas. Hope this helps.