全局变量的值在ValueEventListener中初始化后重置

时间:2016-12-31 09:46:18

标签: android firebase firebase-realtime-database

我有一个名为“bg”的全局变量。它在firebase数据库引用“myRef”

的ValueEventListener中初始化

但是如果我尝试在valueeventlistener块之外使用变量的值,则该变量为空。好像它正在被重置一样。

我对android很新。请让我知道什么是错的。

代码如下:

package com.example.tejasvi.donorfinder;

import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;

import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    private FirebaseAuth mAuth;

    public String latlng[],bg;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_maps);

         mAuth = FirebaseAuth.getInstance();

         Bundle bundle = getIntent().getExtras();

         String s= bundle.getString("Phone");  

         String path="Active Requests/"+mAuth.getCurrentUser().getUid()+"/"+s+"/Blood Group";

        FirebaseDatabase database = FirebaseDatabase.getInstance();
        DatabaseReference myRef = database.getReference(path);   


        myRef.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                bg=dataSnapshot.getValue().toString();
                }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Toast.makeText(MapsActivity.this, "Error", Toast.LENGTH_LONG).show();

            }
        });

        Toast.makeText(MapsActivity.this, bg, Toast.LENGTH_SHORT).show();  //bg is empty here

        SupportMapFragment mapFragment = (SupportMapFragment)    getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        }
}

dataSnapshot.getValue()的值是“A + ve”

JSON文件如下:

{
  "Active Requests": {
    "3R8XGIM5uSRv3sxQZ2sqqUnIjQ62": {
      "9849949799": {
        "Blood Group": "B+ve",
        "Date of Requirement": "3/1/17",
        "Direct or Replacement?": "Direct donation",
        "Donation Type": "Whole Blood",
        "For Self?": "Yes",
        "Hospital Name": "Shekhar Hospital",
        "Location": "12.945793000000002,77.56759339999999",
        "Name": "Poorna Chandra Tejasvi",
        "Units": "2"
      }
    },
    "YL5oVxmua4gktNM2TwwPavL1Tj32": {
      "123456789": {
        "Blood Group": "A+ve",
        "Date of Requirement": "1/1/17",
        "Direct or Replacement?": "Direct donation",
        "Donation Type": "Whole Blood",
        "For Self?": "No",
        "Hospital Name": "Columbia Asia Hospital - Hebbal",
        "Location": "13.0509869,77.5937892",
        "Recipient Name": "jssnxn",
        "Recipient Relation": "Married",
        "Units": "3"
      }
    }
  }
}

1 个答案:

答案 0 :(得分:4)

这里没有魔力。您只是看到异步加载的影响,大多数现代Web都是在这种影响下构建的。

如果您在调试器中运行代码或添加一些日志语句,这是最容易理解的,如下所示:

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference(path);   

System.out.println("Before adding listener");
myRef.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        System.out.println("In onDataChange");
    }

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

System.out.println("After adding listener");

当您运行这样的代码时,它将打印:

  

添加侦听器之前

     

添加监听器后

     

在OnDataChange

这可能不是您所期望的,但它是处理Firebase时的预期行为,也是最现代的Web API。由于加载数据可能需要一段未知的时间(毕竟必须从互联网上的某个地方获取),代码不会等待数据返回,而是继续在您之后继续使用该行附上了听众。然后,当数据可用时,它会调用您的onDataChange(),您可以使用该数据。

这种行为起初令人难以置信,所以如果不能立即明白,请不要担心。要认识到的重要一点是行为是正常的,是现代网络编程的一部分。所以不要试图解决它(即让代码等待数据)。相反:尝试将您的问题重新构建为一个更适合这种异步性质的模型。

我发现从#&#34开始重新构建我的问题最简单;首先加载数据,然后在吐司中显示它" to"开始加载数据,然后在加载数据时,将其显示在toast中#34;。这转换为以下代码:

FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference(path);   

myRef.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        bg=dataSnapshot.getValue().toString();
        Toast.makeText(MapsActivity.this, bg, Toast.LENGTH_SHORT).show();  
    }

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