I have a situation where I have to do a server call from Android and based on the result of the call ( result would be either true or false) I want to proceed ahead in the code flow and pop a Dialog based on this result. Till the call is complete I don’t wish to proceed ahead in the code flow or logic. In short, I want to carry out a sync operation
At the server side, I will receive a HTTP Post request from android client and based on the parameters in the POST I do some processing by fetching values from the DB and return back true or false to android client.
To carry this out correctly on Android side, I researched and got two options.
Using Handler with AsyncTask does not work in my case because if
I use AsyncTask with Handler, the task result will arrive
sometime in future in Handler and the calling function will return
immediately whereas I want the calling function invoking
AsyncTask to finish i.e. wait till the server returns backs before I
proceed ahead .
The other option that I came across was to use
AsyncTask get() method . Since I am not carrying out a long running
task and rather performing a simple calculation on serverside, this
may not cause a an ANR situation even if I block the UI thread.
Are there any better options of carrying this out ? Is AsyncTask get() here actually one of the correct uses of get() ?
Related
I'm trying to determine whether or not I download data in my android application. I can do this by making the method return true when it does download data, but the listener doesn't seem to be invoked until all other code is finished running (meaning it waits until a pause in your code). So I'm wondering if there is a way to sort of "forcibly" invoke these listeners? Perhaps by creating the listener in a different thread? Would this work or would it be a waste of time? I've already tried to sleep on the main thread for a few seconds, but that doesn't seem to do it either. If it wouldn't work, could you explain when exactly these listeners are invoked? Thanks in advance.
To add onto my question, I am NOT using the realtime database. I understand how realtime triggers work, but I am using the Firestore, so I am only getting data once, not getting realtime updates :)
As you have already noticed with the API calls that deal with reading and writing data are fully asynchronous. This means that the call always returns immediately, without blocking the code to wait for a result. The results come some time later, whenever they’re ready, since it may take some time for this. Depending on your connection speed and the state, it may take from a few hundred milliseconds to a few seconds before that data is available. So Firebase, already is using another thread (other than the main thread) to get the work done.
Calling a synchronous function on your app’s main thread could freeze the app indefinitely, which is a terrible UX. On Android, it could also soft-crash with an Application Not Responding (ANR) dialog.
Doug Stevenson, has explained in his post everything that you need to know about Fireabse asynchronous behaviour and what you need to do/avoid when dealing with Firebase.
I feel that the answer to this question is too obvious, but part of me still wants to ask it anyway.
I am creating an Android app that makes several HTTP POST/GET requests using APIs when the app is launched for the first time by the user. All these requests are made by launching Asynctasks within the activity.
For example, there is an activity where athe user has to select an item from a list retrieved from the API. After he selects one, a progress bar is displayed to the user while the app sends the selection to the API to retrieve another list, and in the next activity, the user selects items from this list. Clearly, the user can't go this second list until a response has been received from the server after the app sends it the first list's selection.
In such a case, is there any point in using an Asynctask to send the selection of the first list, since the user is prevented from doing anything (by being shown a progress bar) until a response is received and the next activity is started. Wouldn't it make the code less complex if I just made the API call on the main thread?
I hope this wasn't too confusing.
Thanks
I got your doubt completely. Good question. The root cause of the doubt because you are thinking you don't need to interact with the app till the process completes. But you actually want to. Event the progress bar will freeze if you could do something like it.
Ok, let's just assume you don't even have a ProgressBar. However, handling the different UI components such as Spinners, EditTexts is not the only duty of the main thread. It should define different callbacks in the activity lifecycle. Doing big tasks in main thread will also freeze callbacks like onPause(), onStop() etc. That is why the 'NetworkOnMainThreadException' is being thew.
Basically you cannot call the api on main thread as it will block the UI. Also now Android does not allow it to happen and throws 'NetworkOnMainThread Exception'. Its fine to use Asynctask for any task that takes few seconds and you get the callback in it , which in your case is required before you proceed to next screen.
Best way to do it is by using Networking libraries:
Refer this
https://developer.android.com/training/volley/simple.html
First of all you cannot do netwok call on main thread, it will raise NetworkOnMainThreadException , You can still by pass this exception by adding the couple of following lines in your activity
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
but it is always recommended to perform network operation in background,
else it may cause your app to stop responding, and can result in the OS killing your app for being badly behaved , go through this article once link
Any operation that takes more than a few seconds to perform should be added in a separate thread. All network operations should be performed on AsyncTask or do have a look at RxJava and RxAndroid. To be specific to your operation, any UI Operations during a network call can be performed in onPostExecute. If you're working with thread class then use a Handler.
As others mentioned, if main thread is used for network operation, it would make your app unresponsive.
User may want to start a different flow in your app by starting an activity from menu or action bar whatever is available in your app to start other flow.
I am working on JOB queue. Here the scenario is i am storing 3 api calls in job queue. The first API is having more information in json. but last two is having less information. According to the priority when network is available it is calling those apis one bye one in right order. but as the first api is having more information it is taking more time to hit the server so it is reaching the server at last. Is there any way where after hitting the server we can able to run the rest APIs?
To manage your network request one after other you can Use AsyncTask.
AsyncTask have 3 main method i.e
1)onPreExecute - can perform any Ui update while calling network request.
2)doInBackground - which run in background thread not on main thread.
3)onPostExecute - after doinbackground process onPostExecute will call.
like this you can call your request when first request get completed ,So on first onPostExecute , call second request and so On.
I hope like this you can manage your network request in serial way. Thanks :)
I've read alot of different recommendations on how to use locks - but the behavior of my current code in both IOS and Android does not behave correctly.
What I'm trying to do is build a queue system with a HTTP Request. If a Request fails, it should be the first request to be retried. Both send and add to queue is in the same method, so it shall not add a new object into the queue until the previous request has finished. If one fails and when the next request gets added it would send two requests (in the same package and clearing the queue).
Android:
// Java
synchronized(locker)
{
Add object to a queue if there is a new object to be added
If any objects in queue - send request with AsyncTask
}
IOS:
// Objective-C
#synchronized(locker)
{
Add object to a queue if there is a new object to be added
If any objects in queue - send request with NSURLSessionDataTask
}
...and on fail, do not remove the object from the queue.
In this case - I am guessing that the lock does get released and another thread could possibly be sending the next request right away and come first since the tasks are dispatched in another thread?
I've tried with normal locks with some success on Android and complete failure on iOS where the entire system freezed up. Since then I've read about locking a lock on IOS that it has to be unlocked by the same thread - would a dispatch_async(dispatch_get_main_queue()... on the entire method work or would I have to dispatched it again when the completitionHandler finishes? Can I be certain that the completitionHandler is called on the same thread as the method creating it?
It's very important that each package are sent in the correct order. What is the best approach towards a multithreaded HTTP Request system like this?
Don't spawn new threads by AsyncTask or NSURLSessionDataTask. If you need the threads to serialize, i.e. at most one of them may run at the same time, and the next one has to wait for the first one to finish completely, there's absolutely no reason to run multiple threads.
You're going to want one (1) thread for all requests, and maybe send data to it using a queue. Otherwise, the UI might freeze while sending http requests.
Background
I have an AsyncTask (call it uploadHeader) that uploads some data to a server.
I have a second AsyncTask (uploadDetail) that uploads some related data, which requires the initial data to have been uploaded: the header upload returns an id issued by the server, which is used to update the local detail records, before they're uploaded.
If at the time uploadHeader was initially called there were connectivity issues, the header info won't have been uploaded.
So at the start of uploadDetail.doInBackground() I check the status of the local header record to see if it has already been successfully uploaded to the server, and if not, call an uploadHeader.get() to upload the header and wait to get the id back, before I upload the detail records.
Problem
It just seems to hang at the get() call. Debugging it, it seems to be creating a FutureTask and then looping somewhere inside that. It looks as if the second AsyncTask is being queued to run after the first one finishes, which it never does since it's waiting on the second.
I've read a number of other posts/articles on calling one AsyncTask from another, but they all seem to be focused on getting the two to run in parallel. I want this to block, until the other task finishes. It's also been mentioned that "execute(Params...) must be invoked on the UI thread.", none of the articles mention get(). Or is get() basically identical to execute() apart for waiting for the result?
As a workaround, I could put the http call to upload the header in a separate class and call that from both uploadHeader and uploadDetail, so uploadDetail wouldn't need to create an uploadHeader task.
I'd just like to understand why it's not working as it is.
get() will block your execution until the second AsyncTask returns a value, don't do this if your first AsyncTask is doing some work that repercutes on the user interface of even in the workflow you've designed.
I'd definitely use Handlers on both AsyncTasks to communicate between them, even another one for the UI if you need to. You may find a good example here. For reference, look here.