使用Android / Firebase实时数据库时,Single.Create()... blockingGet()在RxJava 2.1.3中挂起

时间:2017-08-30 16:39:01

标签: android firebase firebase-realtime-database rx-java rx-java2

使用以下模式同步从Firebase实时数据库获取数据时:

OnCreate

它会挂起并产生ANR错误。如果我使用相同的Firebase"内脏"在Single之外,它发射得很好。没有Firebase代码的Single也会触发,因此两者之间似乎存在一些不兼容性。

有什么想法吗?

2 个答案:

答案 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);
         }
     });