Reputation: 1735
I am trying to figure out how to do something with data returned from an AsyncTask
.
I have an activity where I am calling an async Firebase get operation (operation existing in a different class), and I want to update an TextView
existing in the Activity with the size of the ArrayList retrieved. Here is my Firebase call that get's called in Activity onCreate:
public void getAttendants() {
ArrayList<AttendModel> attendees = new ArrayList<AttendModel>();
FirebaseConnection.getInstance().getAllAttendeesFor(uuid, attendees);
Log.d("attendees", String.valueOf(attendees.size()));
}
and here is my Firebase operation :
public void getAllAttendeesFor(String UUID, final ArrayList<AttendModel> attendArray) {
final DatabaseReference attendObjects = getDatabaseTableWith(Constants.tableAttendObject);
Query queryRef = attendObjects.orderByChild(Constants.taAttendObjectUUID).equalTo(UUID);
queryRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
HashMap<String, Object> attend = (HashMap<String, Object>) postSnapshot.getValue();
String UUID = (String) attend.get(Constants.taAttendObjectUUID);
String userUsername = (String) attend.get(Constants.AttendObjectUserUsername);
AttendModel attendModel = new AttendModel(userUsername, UUID);
attendArray.add(attendModel);
//here would like to notify or somehow return the attendArray
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
What is the best approach of this in Android? Is there the possibility to implement an Adapter of sorts or a completion handler?
Upvotes: 1
Views: 4599
Reputation: 10267
What you are looking for is Callback interface, as for your needs you need simple interface that implement single method with single parameter, as there is no out of the box convention for Java 6 (Android Java version) you can easily create it by yourself:
interface Callback {
void act(List<AttendModel> models);
}
pass it as an argument to the firebase wrapping method, and call it with the result.
public void getAllAttendeesFor(String UUID, final ArrayList<AttendModel> attendArray, final Callback callback) {
final DatabaseReference attendObjects = getDatabaseTableWith(Constants.tableAttendObject);
Query queryRef = attendObjects.orderByChild(Constants.taAttendObjectUUID).equalTo(UUID);
queryRef.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
HashMap<String, Object> attend = (HashMap<String, Object>) postSnapshot.getValue();
String UUID = (String) attend.get(Constants.AttendObjectUUID);
String userUsername = (String) attend.get(Constants.AttendObjectUserUsername);
AttendModel attendModel = new AttendModel(userUsername, UUID);
attendArray.add(attendModel);
callback.act(attendArray)
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
then in your upper level method:
public void getAttendants() {
ArrayList<AttendModel> attendees = new ArrayList<AttendModel>();
FirebaseConnection.getInstance().getAllAttendeesFor(uuid, attendees,
new Callable<List<AttendModel) {
void act(List<AttendModel> attendees){
//here you can update the UI
Log.d("attendees", String.valueOf(attendees.size()));
}
};
}
Just be aware that you can update the UI only if onDataChange method of the firebase query is called on the main thread.
Upvotes: 3