Reputation: 5840
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?
Upvotes: 0
Views: 480
Reputation: 2764
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.
Upvotes: 0
Reputation: 13129
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 !
Upvotes: 1
Reputation: 24211
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!
Upvotes: 0