问题
I know this might be a common question but I am really stuck at this point.
I am receiving data from 2 multiple locations and after I received from both I need to continue executing and than return that data to the calling method.
I am aware of this thread: https://stackoverflow.com/a/33204705/1820644 but it doesn't fit here actually as I need to return the data to the calling method.
For the method that blocks UI thread I can call it from AsyncTask, there is no problem. But how can I return data to the calling method that I have successfully completed execution.
This is inside my helper class
// This method should be called in AsyncTask
public boolean doComputation() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("activity")
.child(id);
ref.child("path1").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Call 1 completed
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
ref.child("path2").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Call 2 completed
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
// Some more to do
// Need to return true after execution complete
return true;
}
I can not return true inside of the onDataChange as it will counted for onDataChange method and not for doComputation.
I can perform the calculation by moving it to another method and after each onDataChange callback I can check for variable count, and if it is 2 I can perform the calculations. But after it completes I need to notify it to the calling method that execution is completed.
This is a little bit tricky with Firebase. But, I am really stuck at it right now. Any help will be much appreciated. Thank you.
回答1:
I have gone with the Tasks API which Firebase uses already. Its great.
As mentioned by @qbix , This answer does the same thing. The example in the answer explains good.
You can also find video link of this API instructions here.
I have tried and tested it. Solves my problem.
回答2:
Depends on the case, what I usually do is to set a flag after each listener completed its job and then call a method to check the flags. If they are all completed, then do the next operation.
For example
private Boolean listener1Completed;
private Boolean listener2Completed;
public void addListeners() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("activity")
.child(id);
ref.child("path1").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
listener1Completed = true;
checkListenerStatus();
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
ref.child("path2").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
listener2Completed = true;
checkListenerStatus();
}
@Override
public void onCancelled(DatabaseError databaseError) {}
});
}
private void checkListenerStatus() {
if (listener1Completed && listener2Completed) {
// do computation
}
}
回答3:
Since firebase works in another thread you can't return desired result instantly. You have to create callback to notify the caller when your result already received. You can achieve this using interface read here
Another way. You can get result from Asynctask Return a value from AsyncTask in Android
Or you can pass your class in parameter (not in AsyncTask job)
public void doComputation(yourCallerClass cls) {
//firebase result.....void
cls.YourResult(trueOrFalse);
.....
}
in your caller class instance eg. yourCallerClass
...
public void YourResult(boolean result){
// do stuff
}
来源:https://stackoverflow.com/questions/38685879/continue-execution-after-data-received-from-multiple-location-in-firebase