简体   繁体   中英

update UI after two async operations

I am using google Firebase database in android. I need two fetch two set of data from database - userInfo and assignmentInfo. Then I need to combine them and show the data in a recycler view. What is the best way to approach this? As the fetching of data is async, this is getting messy.

One way i can think of is, check in both async functions success if other has completed. If so, get its data, combine and initialize the adapter. Is this the best way do this?

I have solved this kind of problem when i had to download something from a database before login in the user into the app, with this i fixed this problem.

To use ObservableInteger you can do this

first declare it

private ObservableInteger mObsInt;

then in your onCreate you will have a listener waiting for the values of the mObsInt to change, after those values change you can do anything you want

//Listener
        mObsInt = new ObservableInteger();
        mObsInt.set(0);

        mObsInt.setOnIntegerChangeListener(new OnIntegerChangeListener()
        {
            @Override
            public void onIntegerChanged(int newValue)
            {
                if (mObsInt.get()==1)
                   //Do something if the first asyncTask finishes
                if (mObsInt.get()==2){
                   //Do something if the second asyncTask finishes, in this case i just go to another activity when both asyncTasks finish
                    Intent mainIntent = new Intent().setClass(LoginActivity.this, Principal.class);
                    startActivity(mainIntent);
                    finish();
                }
            }
        });

So, how it works

ObservableInteger will be looking for changes in the variable mObsInt , so lets say if mObsInt is equal to 1 it will do something, if is equal to 2 will do another thing, so, to solve this problem with 2 asynctasks is easy, when one of the asynctasks finishes mObsInt will be equal to 1 , if the other asyncTask finishes so mObsInt will be mObsInt++ , and then your mObsInt will be equal to 2, the listener will be waiting for the values, and then do what you want to do when the values match your if statment at the onCreate method

now, just in your asynctasks just put in your onPostExecute() method this line

mObsInt.set(mObsInt.get()+1);

so if the first async finish, mObsint == 1 , if the second finish mObsInt == 2, and then you handle what you want to do in your onCreate method

hope this helps for you, it helped me

You can get more info at this doc : https://developer.android.com/reference/android/databinding/ObservableInt.html

happy coding !

The simplest way I use in projects w/o Rx/Coroutines/other stuff. Just create AtomicInteger . Init it with value equals number of async operations. Then in each callback of your async functions call this:

if(counter.decrementAndGet == 0) { your_final_action} .

If you need some help with other ways like I mentioned before, feel free to ask me.

This can be achieved using a simple variable which will be incremented or will be keeping a flag if the both data is available to be merged and returned successfully from Firebase. However, this is neither the best approach and nor will work all the time as it can fail if the both async thread tries to update the flag at the same time. Then with the implementation given above, will work only if you can make the whole operation thread-safe.

If you consider building a thread-safe implementation on your own, that is not so difficult either. You might just consider using a Synchronized function which will update the flag you are keeping to detect if the both data from firebase is fetched.

However, I would suggest to get your implementation done using a LocalBroadcastReceiver . Which is easier to implement and this is an Android solution. Though there might be a several other approaches which are great as well, I think the implementation with BroadcastReceiver will serve your purpose fully.

You can check this answer for checking the implementation of a BroadcastReceiver . When the first part of the data is fetched from firebase, send the broadcast to be received by the BroadcastReceiver in your Activity and set a flag value for example, 1. Then when the second part is received, you will have to set the value to 2 again by just sending the broadcast on getting response from firebase. And then, when the value is found 2, that means the both operations has completed and now you can merge the two lists.

To avoid the overall thread-safe and fail safety coding overhead, you might consider fetching the data from firebase, synchronously. On getting the data for the first part, initiate the fetch operation for the second part for better control over your code.

I have just put some ideas, pick any that suits you. Hope that helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM