为啥触发 Firebase onDataChange() 方法后,我的 Google Map 会不断创建新的地图实例?

Posted

技术标签:

【中文标题】为啥触发 Firebase onDataChange() 方法后,我的 Google Map 会不断创建新的地图实例?【英文标题】:Why does my Google Map keep creating new map instances after Firebase onDataChange() method triggered?为什么触发 Firebase onDataChange() 方法后,我的 Google Map 会不断创建新的地图实例? 【发布时间】:2019-05-31 10:19:48 【问题描述】:

从 Firebase 读取坐标时,我在 MapsActivity 上更新 Google 地图时遇到问题。我想要它,以便每当检测到数据库更改(此点的纬度或经度发生更改)时,地图上的标记会更改以匹配在数据库中找到的新纬度和经度。

但是,在执行此操作时,我开始意识到,每当更新数据库并调用 onDataChange() 时,之后都会调用 onCreate(),从而导致要创建 Map 的另一个实例。出于这个原因,当我尝试返回手机(返回按钮)时,我偶然发现了以前的地图(在数据库更改之前)。

此外,即使未打开应用程序,地图也会打开。在 onMapReady() 中调用数据库查询。代码执行如下:

预数据库更改:

onCreate()

onMapReady()

onDataChange() -- onMapReady() 内部

然后:

数据库更改后:

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);
        
    );


【问题讨论】:

您是否尝试过使用addListenerForSingleValueEvent 而不是addValueEventListener?是这样的吗? 【参考方案1】:

您不应该在每次调用 onCreate() 方法时创建地图实例。相反,您需要在创建后保存地图实例。然后检查该实例是否存在,然后再创建另一个地图实例(即在onDataChange() 被触发之后)。

【讨论】:

嗨,Sourav,“创建地图实例”是指 mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this);或者你的意思是回调 onMapReady() 的第一行,当我们获取 GoogleMap 并将其存储在一个值中时。 我认为您应该将相关代码发布到您的问题中,这将有助于更好地识别。 嗨,Sourav,我在帖子中添加了 onCreate() 方法!【参考方案2】:

感谢大家的回复!

我终于修好了我的程序;这实际上是一个简单的错误,甚至在我一直在看的活动中都没有。当在一个活动中调用 onDataChange 时,也会在所有其他活动中的所有实例中调用它。我在之前的活动中不小心启动了 MapsActivity onDataChange(),所以每次数据库中的数据发生变化时,都会调用 onCreate()!

【讨论】:

以上是关于为啥触发 Firebase onDataChange() 方法后,我的 Google Map 会不断创建新的地图实例?的主要内容,如果未能解决你的问题,请参考以下文章

输入 OnDataChange FireBase Android 时应用程序崩溃

Wear OS 3 设备未触发 Wearable onDataChanged

Firebase onDataChange Listener 是不是总是在应用程序关闭后自动删除?或者,不是而且账单也在增加?

为啥我的 firebase onAuthStateChanged() 触发多次? (反应原生)

在 Firebase 中使用事务时,为啥 onChildChanged() 在 onComplete() 之前触发?

使用 Firebase 实时数据库参考填充 RecyclerView