我有一个名为“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"
}
}
}
}
答案 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();
}
});