【问题标题】:Return value from valueEventListener java从 valueEventListener java 返回值
【发布时间】:2017-02-09 14:08:54
【问题描述】:

我试图返回一个布尔值,但返回的值始终为 false,在这种情况下为 0。

check 变量是一个实例变量,按下按钮时会调用下面的函数。

private boolean checkAnswerSubmission() {

    DatabaseReference answerDatabase = FirebaseDatabase.getInstance().getReference().child("userPuzzleHistory").child(uid);
    answerDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.hasChild(String.valueOf(imagename))) {
                check = 1;
            } else {
                check = 0;
            }
     //here the value check is working fine but the value cannot be returned from here.
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    //here the value returned is always 0
    if (check == 1)
        return true;
    else
        return false;

}

【问题讨论】:

  • Java 没有全局变量。
  • 我的错。已经做出改变..任何帮助都会很棒@shmosel
  • 创建你的静态变量。
  • 数据库引用不是在与运行您的函数的线程相同的线程上完成的。它只是为异步调用添加了一个侦听器,该侦听器仅在从服务器接收到数据时才调用。所以你应该把所有你需要的函数调用都放在监听器里面。

标签: android firebase firebase-realtime-database


【解决方案1】:

与所有异步操作一样,我经常以回调方式进行。

您的解决方案可以这样工作:

  1. 创建一个简单的回调接口(我的库中有一个我在几乎每个应用程序中使用的库)

    public interface SimpleCallback {
        void callback(Object data);
    }
    
    // You could do it as well generic, that's what I do in my lib:
    public interface SimpleCallback<T> {
        void callback(T data);
    }
    

然后像这样重新设计方法的签名:

private void checkAnswerSubmission(@NonNull SimpleCallback<boolean> finishedCallback) {

    DatabaseReference answerDatabase = FirebaseDatabase.getInstance().getReference().child("userPuzzleHistory").child(uid);
    answerDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            // This will simple call your callback containing a boolean true/false
            finishedCallback.callback(dataSnapshot.hasChild(String.valueOf(imagename)));
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

你用:

checkAnswerSubmission(new SimpleCallback<boolean>() {
   @Override
   void callback(boolean data) {
       if (data) {
          // true was returned
       } else {
          // false was returned
       }
   }
});

【讨论】:

  • 谢谢@Grisgram
  • 这是一个绝妙的解决方案。我花了数周时间尝试在 Firebase 中处理异步调用,这非常完美! ?
【解决方案2】:

数据库引用不是在与运行您的函数的线程相同的线程上完成。它只是为异步调用添加了一个侦听器,该侦听器仅在从服务器接收到数据时进行。

因此,您的程序会初始化一个侦听器并继续执行此行中的下一条语句。

answerDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.hasChild(String.valueOf(imagename))) {
                check = 1;
            } else {
                check = 0;
            }
     //here the value check is working fine but the value cannot be returned from here.
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

现在程序不等待从它执行的服务器接收到响应:

if (check == 1)
        return true;
    else
        return false;

因此,如果您的检查值已初始化,它很可能会将 0 作为值并始终返回 false。

【讨论】:

    猜你喜欢
    • 2017-05-14
    • 1970-01-01
    • 2011-01-19
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多