为什么我的 Google 地图在触发 Firebase onDataChange() 方法后继续创建新的地图实例?
Why does my Google Map keep creating new map instances after Firebase onDataChange() method triggered?
从 Firebase 读取坐标时,我无法更新 MapsActivity 上的 Google 地图。我想要它,以便每当检测到数据库更改(该点的纬度或经度更改)时,地图上的标记会更改以匹配在数据库中找到的新纬度和经度。
但是,在执行此操作时,我开始意识到每当数据库更新并调用 onDataChange() 时,此后都会调用 onCreate(),从而导致创建另一个 Map 实例。出于这个原因,当我尝试返回我的 phone(后退按钮)时,我偶然发现了以前的地图(在数据库更改之前)。
此外,即使未打开应用程序,地图也会打开。在 onMapReady() 中调用数据库查询。代码执行如下:
数据库更改前:
onCreate()
onMapReady()
- onDataChange() -- 在 onMapReady() 内部
然后:
Post-数据库更改:
onDataChange()
onCreate()
onMapReady()
- onDataChange() -- 在 onMapReady() 内部
有人知道为什么会这样吗?
编辑:如果需要注意这一点,我曾尝试将数据库查询移动到 onCreate() 但无济于事——我在之后移动了它:
mapFragment.getMapAsync(this);
编辑:onCreate()
的代码块
@Override
protected void onCreate(Bundle savedInstanceState) {
Paper.init(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
StartPinActivity.databaseChildren.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot user : dataSnapshot.getChildren()) {
Child child = user.getValue(Child.class);
assert child != null;
if (child.getPhoneNumber().equals(ProfileAdapter.clickedProfile.getPhoneNumber())) {
if (childMarker == null) {
LatLng childLocation = new LatLng(child.getLatestLat(), child.getLatestLong());
MarkerOptions childMarkerOptions = new MarkerOptions().position(childLocation).title("Child's location");
childMarker = mMap.addMarker(childMarkerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(childMarkerOptions.getPosition()));
Toast.makeText(MapsActivity.this, "A new child location has been received.", Toast.LENGTH_SHORT).show();
break;
}
else {
LatLng childLocation = new LatLng(child.getLatestLat(), child.getLatestLong());
MarkerOptions childMarkerOptions = new MarkerOptions().position(childLocation).title("Child's location");
childMarker.setPosition(childMarkerOptions.getPosition());
mMap.moveCamera(CameraUpdateFactory.newLatLng(childMarkerOptions.getPosition()));
Toast.makeText(MapsActivity.this, "A new child location has been received.", Toast.LENGTH_SHORT).show();
break;
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Button finalizeButton = findViewById(R.id.finalize);
finalizeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
StartPinActivity.databaseParents.child(Paper.book().read(CURRENT_ID).toString()).child("geofences").setValue(geofenceList);
}
});
}
您不应该在每次调用 onCreate()
方法时都创建地图实例。相反,您需要在创建后保存地图实例。然后在创建另一个地图实例之前检查实例是否存在(即在 onDataChange()
被触发之后)。
谢谢大家的回复!
我终于修好了我的程序;这实际上是一个简单的错误,甚至在 activity 我一直在看的时候都没有。当在一个 activity 中调用 onDataChange 时,它也会在所有其他活动的所有实例中被调用。我在之前的 activity 中不小心启动了 MapsActivity onDataChange(),所以每次我的数据库中的数据发生变化时,都会调用 onCreate()!
从 Firebase 读取坐标时,我无法更新 MapsActivity 上的 Google 地图。我想要它,以便每当检测到数据库更改(该点的纬度或经度更改)时,地图上的标记会更改以匹配在数据库中找到的新纬度和经度。
但是,在执行此操作时,我开始意识到每当数据库更新并调用 onDataChange() 时,此后都会调用 onCreate(),从而导致创建另一个 Map 实例。出于这个原因,当我尝试返回我的 phone(后退按钮)时,我偶然发现了以前的地图(在数据库更改之前)。
此外,即使未打开应用程序,地图也会打开。在 onMapReady() 中调用数据库查询。代码执行如下:
数据库更改前:
onCreate()
onMapReady()
- onDataChange() -- 在 onMapReady() 内部
然后:
Post-数据库更改:
onDataChange()
onCreate()
onMapReady()
- onDataChange() -- 在 onMapReady() 内部
有人知道为什么会这样吗?
编辑:如果需要注意这一点,我曾尝试将数据库查询移动到 onCreate() 但无济于事——我在之后移动了它:
mapFragment.getMapAsync(this);
编辑:onCreate()
的代码块 @Override
protected void onCreate(Bundle savedInstanceState) {
Paper.init(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
StartPinActivity.databaseChildren.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot user : dataSnapshot.getChildren()) {
Child child = user.getValue(Child.class);
assert child != null;
if (child.getPhoneNumber().equals(ProfileAdapter.clickedProfile.getPhoneNumber())) {
if (childMarker == null) {
LatLng childLocation = new LatLng(child.getLatestLat(), child.getLatestLong());
MarkerOptions childMarkerOptions = new MarkerOptions().position(childLocation).title("Child's location");
childMarker = mMap.addMarker(childMarkerOptions);
mMap.moveCamera(CameraUpdateFactory.newLatLng(childMarkerOptions.getPosition()));
Toast.makeText(MapsActivity.this, "A new child location has been received.", Toast.LENGTH_SHORT).show();
break;
}
else {
LatLng childLocation = new LatLng(child.getLatestLat(), child.getLatestLong());
MarkerOptions childMarkerOptions = new MarkerOptions().position(childLocation).title("Child's location");
childMarker.setPosition(childMarkerOptions.getPosition());
mMap.moveCamera(CameraUpdateFactory.newLatLng(childMarkerOptions.getPosition()));
Toast.makeText(MapsActivity.this, "A new child location has been received.", Toast.LENGTH_SHORT).show();
break;
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
Button finalizeButton = findViewById(R.id.finalize);
finalizeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
StartPinActivity.databaseParents.child(Paper.book().read(CURRENT_ID).toString()).child("geofences").setValue(geofenceList);
}
});
}
您不应该在每次调用 onCreate()
方法时都创建地图实例。相反,您需要在创建后保存地图实例。然后在创建另一个地图实例之前检查实例是否存在(即在 onDataChange()
被触发之后)。
谢谢大家的回复!
我终于修好了我的程序;这实际上是一个简单的错误,甚至在 activity 我一直在看的时候都没有。当在一个 activity 中调用 onDataChange 时,它也会在所有其他活动的所有实例中被调用。我在之前的 activity 中不小心启动了 MapsActivity onDataChange(),所以每次我的数据库中的数据发生变化时,都会调用 onCreate()!