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.
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 am doing an android app and I have an UI to show some data received from the server. The data is saved in the db in a controller.
When the app is started, this is what it is doing:
the controller instance is initialized on the Ui thread, it is singleton. The initialization is lightweighted. The UI will call the controller method to get the data saved in memory and show it.
having a worker thread to execute some controller method to read the data from db and save it in the cache in memory and notify UI after get it.
whenever there is some new data, the server will send a push to the client where an intentservice is started and the controller talks to the server to get the data and update the cache and after it completes, it notifys UI.
So the question is the 2 and 3, since both are running in different threads, so in order to make sure the db must be read and save in cache first, I have a flag in 3) so that before writing the new data in the memory, I always check the flag first. It will work but since I can foresee there will be more operations on the cache probably cross different threads and I really don't want to add the flag checking in all such places, so do we have any pattern/way to make sure the 2) always happens first?
sorry that I didn't find any similar post on it. thanks.
ok do one thing when your statement 2 is complete the execution at the last line of code call a broadcast receiver and inside onRecieve() method which is inside the BroadCastReceiver execute the statement 3.
I used AsyncTask to get html files from server. But when an activity starts, screen becomes white few seconds and displays data when fully downloaded.
I wanted it to display activity's basic layout first(e.g. actionbar) and downloaded data later. So I used Thread and the problem solved.(basic layout is first shown and data later)
I've been knowing AsyncTask do things asynchronously but in my case it didn't.(In doInBackground, I only did network connection)
Does AsyncTask really do things in background?
Does AsyncTask really do things background?
Yes.
Note, though, that AsyncTask is serialized by default, meaning that if you fork multiple AsyncTask instances, they will share a single thread, and the second and subsequent tasks will be queued up waiting until the first task completes. You can avoid this via using executeOnExecutor(), instead of execute(), to run the tasks.
There are other ways of misusing AsyncTask (e.g., calling get()) as well.
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() ?
I have an Activity that displays a text based on data pulled from MySQL server. The problem is that the Activity won't load until data is pulled, which sometimes takes some long seconds or even doesn't load at all, and in the meantime the users gets a black screen.
I tried to pass the mission of getting the data from the server to a service, but also it waits for pulling the data and only then shows the layout of the Activity.
I also tried to make an activity with fixed text and then call the Activity that pulls the data from the server, but still the program wait for the data.
Can you think on a creative solution for it? or maybe a non-creative one as well :)
you can use asynctask for this:
http://developer.android.com/reference/android/os/AsyncTask.html
or you can show a waiting dialog to user until you get your data(do it in separate thread).....
or you can implement a splash screen and there you can fetch data.....
You need to do it inside another thread. Try using AsyncTask class.
The delay is probably due to the call to fetch the data being done on the main thread, also called the UI thread. Processes which take any significant amount of time, and by that I mean even a second or two should be done in a seperate thread. Android provides a class called AsyncTask to help make threading painless.
You mention you tried a service but did you take a look at an IntentService? (Can't link it yet but it's on d.android.com.) I like using them for these kind of tasks cause they handle the threading for you (like an AsyncTask) and it separates concerns better. The IntentService then sends a broadcast message that the activity picks up indicating that the data is available or not. Store the data locally in a sqlite db or as a json/xml file.