使用以下模式同步从Firebase实时数据库获取数据时:
OnCreate
它会挂起并产生ANR错误。如果我使用相同的Firebase"内脏"在Single之外,它发射得很好。没有Firebase代码的Single也会触发,因此两者之间似乎存在一些不兼容性。
有什么想法吗?
答案 0 :(得分:1)
Firebase在ui线程上传递事件,等待blockingGet
死锁的结果。在我看来,您应该重新考虑应用逻辑并使用{{1}}
答案 1 :(得分:0)
由于您要创建自己的Single,因此应在DisposableSingleObserver
中使用subscribeWith
。其次,你不应该像这样调用blockingGet()。原因是默认情况下,您创建的Single or any observable/Processor/Flowable
将被订阅(在主线程上运行其操作)并观察主线程。 BlockingGet()
导致mainThread暂停。这就像在主线程上执行Thread.sleep()
一样。这总是以灾难告终。
最好的选择是重新考虑您尝试输入代码的逻辑。由于Firebase操作本质上是异步的,因此您应该将代码调整为异步模式。
无论如何,您可以执行以下操作来实现您可能尝试做的事情。请注意,我在这里编写了以下代码,因此可能会出现语法错误。
Single.create(new SingleOnSubscribe<String>() {
// your firebase code
@Override
public void subscribe(SingleEmitter<String> e) throws Exception {
FirebaseDatabase.getInstance().getReference("path").orderByChild("child").equalTo("xyz").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
e.onSuccess("My String");
}
@Override
public void onCancelled(DatabaseError databaseError) {
e.onError(databaseError.toException());
}
});
}
})
.subscribeOn(Schedular.io())
.observeOn(AndroidThread.mainThread()) // if you aren't doing intensive/long running tasks on the data you got from firebase
.subscribeWith(new DisposableSingleObserver<String>() {
public void onSuccess(String myString) {
mMyString = myString;
}
public void onError(Throwable t) {
Timber.e("error in fetching data from firebase: %s", t);
}
});