我读到 Firebase 在后台线程上运行其操作,并在 UI 线程上运行回调。
有没有办法运行阻塞的 Firebase 操作?
例如:
我知道 setValue()
不会返回 bool 值,我想问一下是否有类似的 API 可以执行类似以下代码的操作
// we are in a background thread
DatabaseReference ref = FirebaseDatabase.getInstance().getReference();
boolean success = ref.child("user").child("name").setValue("Arthur");
// code is blocked until operation completes
Log.d("MY_TAG", "successfull operation:" + success);
最佳答案
FirebaseDatabase API 不包含 setValue() 的阻塞形式.您可以使用返回的 Task在您自己的工作线程(非主)线程中添加阻塞:
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可用于阻塞读取。因为监听器回调在主线程上运行,所以这段代码只能在另一个线程上运行。如果在主线程上运行,它会死锁。
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");
}
您还可以使用 Task
进行阻塞读取(在主线程之外):
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");
}
关于android - 运行阻塞请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41990966/