【问题标题】:Unable to pass a value between methods in same class in Android无法在Android中同一类中的方法之间传递值
【发布时间】:2018-06-30 00:42:29
【问题描述】:

我已尝试通过在此处遵循不同的解决方案在 2 个方法之间传递一个值,但传递的是 null。

我试图通过的代码:

private void getPrice() {

    DatabaseReference dbRequest = FirebaseDatabase.getInstance().getReference(Common
            .request_tbl).child(riderId).child("details"); // "Requests"
    dbRequest.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot child : dataSnapshot.getChildren()) {
                if (child.getKey().equals("price")) {
                    price = Double.valueOf(child.getValue().toString());
                    Log.d(TAG, "getPrice: price = " + price);
                }
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });
}

我试图将“价格”值传递给:

private void recordData(String riderId) {

    getPrice();
    Log.d(TAG, "recordData: price = " + price);

    ...
}

getPrice() 中 price 的值是应该的,但是当我打印出 recordData() 中的值时,value = null

【问题讨论】:

  • 当您调用 Log 行时,您的 ValueEventListener.onDataChange 方法可能还没有被调用,因为它是一个异步处理。回调方法基本上意味着“每当这将发生时,做 X”。当您的日志行假定变量已被该回调中的值填充时。
  • 是的,它被调用了。我有一个按钮。当我按下按钮时,它会调用 recordData().. 我已经运行了很多次并且分辨率相同。
  • 您正在设置回调。当您调用recordData 时,数据可能根本没有准备好,这就是为什么onDataChange 中的Log 有效而recordData 中的Log 无效。
  • 实际上,数据是先添加到数据库中的,一旦骑手在另一个活动中请求乘车,然后将数据写入数据库,我试图从数据库中检索并放在其他地方通过调用 recordData() 在数据库中。
  • 哦,好的。在onDataChanged 中Double.valueOf(child.getValue().toString()); 是否返回值?

标签: java android firebase-realtime-database


【解决方案1】:

在 cmets 中回答您的问题:您不必在括号内传递参数,因为您正在设置回调。

但是您的问题来自方法的优先级。当您调用recordData 时,该值还不存在。

场景是,在recordData 中执行getPrice() 行,但是执行不会等待getPrice() 完成,因为它是一个回调,并且一旦检索到值就会返回,这可以很久以后。为了证明这一点,您可以查看您的日志。这个日志的可能性是:

Log.d(TAG, "recordData: price = " + price);

将在此之前:

Log.d(TAG, "getPrice: price = " + price);

因此,您最好的选择是在您确切知道值已准备好时执行recordData,或者在onDataChange 中调用它。

【讨论】:

  • 成功了!我所做的是将 recordData() 放在 getPrice() 的 ValueListener 中,它可以工作。 :)
  • @LizGL 完美! :) 很高兴我能帮上忙。祝你好运!
【解决方案2】:

将回调用作 getter 的一部分

private void getPrice(ValueEventListener listener) {
    DatabaseReference dbRequest = FirebaseDatabase.getInstance().getReference(Common
            .request_tbl).child(riderId).child("details"); // "Requests"
    dbRequest.addValueEventListener(listener);
}

叫它

getPrice(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot child : dataSnapshot.getChildren()) {
            if (child.getKey().equals("price")) {
                price = Double.valueOf(child.getValue().toString());
                Log.d(TAG, "getPrice: price = " + price);
                // Call a separate function that actually needs the price here
            }
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
       // Don't ignore your errors!
    }
);
// Note: price will still be null here

【讨论】:

    【解决方案3】:

    您的 getData 没有获取任何数据。它只设置了一个监听器,当有 onDataChanged 事件时会执行该监听器。 (当某些数据发生变化时)。

    目前,它所做的 - 它设置了将等待来自 recordData 的 onDataChanged 事件的侦听器,然后它立即打印出尚未初始化或更改的价格。

    如果你想执行recordData方法,你应该在数据发生变化后执行。

    换句话说,它应该是这样的:

    private void setUpListenerForPrice() {
    
       DatabaseReference dbRequest = FirebaseDatabase.getInstance().getReference(Common
            .request_tbl).child(riderId).child("details"); // "Requests"
       dbRequest.addValueEventListener(new ValueEventListener() {
          @Override
          public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot child : dataSnapshot.getChildren()) {
                if (child.getKey().equals("price")) {
                    price = Double.valueOf(child.getValue().toString());
    
                     // call data recording from the listener, after the price acquires a values.
                     recordData(price);
    
                   // Log.d(TAG, "getPrice: price = " + price);
                }
            }
        }
    
        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });
    }
    

    然后

    private void recordData(double newPrice) {
    
    
    Log.d(TAG, "recordData: price = " + newPrice);
    
    // do other data recording operations
    ...
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-02
      • 1970-01-01
      • 1970-01-01
      • 2020-04-28
      • 2012-07-28
      • 1970-01-01
      相关资源
      最近更新 更多