Die FirebaseDatabase API tut keine Sperrform von setValue() enthalten. Sie können die zurück Task verwenden in Ihrem eigenen Code in einem Arbeiter (nicht-Main) Gewinde hinzufügen Blockieren:
boolean success = false;
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
Task task = ref.child("user").child("name").setValue("Arthur");
try {
Tasks.await(task);
success = task.isSuccessful();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d("MY_TAG", "successfull operation:" + success);
A Semaphore lesen kann für eine Blockierung verwendet werden. Da die Listener-Callbacks im Hauptthread ausgeführt werden, kann dieser Code nur in einem anderen Thread ausgeführt werden. Wenn es im Hauptthread ausgeführt wird, wird es blockiert.
final Semaphore sem = new Semaphore(0);
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("user").child("name").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String name = dataSnapshot.getValue(String.class);
Log.i("MY_TAG", "Name=" + name);
sem.release();
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.e("MY_TAG", "onCancelled: " + databaseError.getMessage());
sem.release();
}
});
try {
sem.acquire();
} catch (InterruptedException e) {
Log.w("MY_TAG", "Interrupted");
}
Sie können auch eine Task
für eine Blockierung lesen verwenden (aus dem Hauptthread):
final TaskCompletionSource<DataSnapshot> taskSource = new TaskCompletionSource<>();
final Task<DataSnapshot> task = taskSource.getTask();
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
ref.child("user").child("name").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
taskSource.setResult(dataSnapshot);
}
@Override
public void onCancelled(DatabaseError databaseError) {
taskSource.setException(databaseError.toException());
}
});
try {
Tasks.await(task);
String name = task.getResult().getValue(String.class);
Log.i("MY_TAG", "Name=" + name);
} catch (ExecutionException e) {
Log.e("MY_TAG", "Read failed: " + task.getException().getMessage());
} catch (InterruptedException e) {
Log.w("MY_TAG", "Read interrupted");
}
Dank Qbix! Dies scheint den Trick für setValue() zu tun. Gibt es eine Möglichkeit, das gleiche mit "Lese" -Operationen zu tun? (d. h. Ersetzen von DatabaseReference addListenerForSingleValueEvent() durch einen Task, auf den ich warten kann? – dors
@dors: Ich habe meine Antwort aktualisiert. –