Android 运行阻塞请求

Android 运行阻塞请求,android,firebase,firebase-realtime-database,Android,Firebase,Firebase Realtime Database,我了解到Firebase在后台线程上运行其操作,在UI线程上运行其回调 是否有办法运行阻止Firebase操作 例如: 我知道setValue()不会返回布尔值,我是问是否有类似的API可以执行以下代码 // we are in a background thread DatabaseReference ref = FirebaseDatabase.getInstance().getReference(); boolean success = ref.child("user").child(

我了解到Firebase在后台线程上运行其操作,在UI线程上运行其回调

是否有办法运行阻止Firebase操作

例如:

我知道
setValue()
不会返回布尔值,我是问是否有类似的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不包括块形式的。您可以在工作线程(非主线程)中使用返回的代码在自己的代码中添加阻塞:

A可用于阻塞读取。由于侦听器回调在主线程上运行,因此此代码只能在另一个线程上运行。如果在主线程上运行,它会死锁

    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");
    }
您还可以使用
任务
进行阻塞读取(脱离主线程):

final TaskCompletionSource taskSource=new TaskCompletionSource();
final Task Task=taskSource.getTask();
DatabaseReference ref=FirebaseDatabase.getInstance().getReference();
ref.child(“用户”).child(“名称”).addListenerForSingleValueEvent(新值EventListener()){
@凌驾
公共void onDataChange(DataSnapshot DataSnapshot){
taskSource.setResult(dataSnapshot);
}
@凌驾
已取消的公共void(DatabaseError DatabaseError){
setException(databaseError.toException());
}
});
试一试{
任务。等待(任务);
字符串名称=task.getResult().getValue(String.class);
Log.i(“我的标签”,“名称=”+名称);
}捕获(执行例外){
Log.e(“我的标签”,“读取失败:”+task.getException().getMessage());
}捕捉(中断异常e){
Log.w(“我的标签”,“读取中断”);
}

谢谢qbix!这似乎对setValue()起到了作用。有没有一种方法可以对“读取”操作执行相同的操作?(即,将DatabaseReference的addListenerForSingleValueEvent()替换为我可以等待的任务?
    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");
    }
    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");
    }