Firebase实时数据库数据触发页面刷新及跳转重复问题求助
问题修复与优化方案
修复后完整代码
public class TournamentFinal extends AppCompatActivity { TextView TeamRedScore, TeamBlueScore; private boolean hasGameEnded = false; private ValueEventListener scoreEventListener; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.tournament_final); final DrawerLayout drawerLayout = findViewById(R.id.drawerLayout); findViewById(R.id.imageMenu).setOnClickListener(view -> drawerLayout.openDrawer(GravityCompat.START)); NavigationView navigationView = findViewById(R.id.navigationView); navigationView.setItemIconTintList(null); NavController navController = Navigation.findNavController(this, R.id.navHostFragment); NavigationUI.setupWithNavController(navigationView, navController); navigationView.setNavigationItemSelectedListener(menuItem -> { switch (menuItem.getItemId()) { case R.id.home: startActivity(new Intent(TournamentFinal.this, MainActivity.class)); finish(); break; case R.id.setting: startActivity(new Intent(TournamentFinal.this, SettingActivity.class)); break; case R.id.support: startActivity(new Intent(TournamentFinal.this, SupportActivity.class)); break; case R.id.about_us: startActivity(new Intent(TournamentFinal.this, InfoActivity.class)); break; case R.id.share: startActivity(new Intent(TournamentFinal.this, ShareActivity.class)); break; case R.id.game: startActivity(new Intent(TournamentFinal.this, TournamentFinal.class)); break; } return true; }); BottomNavigationView bottomNavigationView = findViewById(R.id.bottom_navigation); bottomNavigationView.setOnNavigationItemSelectedListener(item -> { switch (item.getItemId()){ case R.id.home: startActivity(new Intent(TournamentFinal.this, MainActivity.class)); finish(); break; case R.id.setting: startActivity(new Intent(TournamentFinal.this, SettingActivity.class)); break; case R.id.game: startActivity(new Intent(TournamentFinal.this, TournamentFinal.class)); break; } return false; }); TeamRedScore = findViewById(R.id.team_red_score); TeamBlueScore = findViewById(R.id.team_blue_score); fetchdata(); } public void fetchdata(){ DatabaseReference reference = FirebaseDatabase.getInstance().getReference().child("Team_score"); scoreEventListener = new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { if (hasGameEnded) return; String redScoreStr = snapshot.child("red_score").getValue(String.class); String blueScoreStr = snapshot.child("blue_score").getValue(String.class); if (redScoreStr != null) { TeamRedScore.setText(redScoreStr); int redScore = Integer.parseInt(redScoreStr); if (redScore == 5) { hasGameEnded = true; reference.removeEventListener(this); startActivity(new Intent(TournamentFinal.this, Red_win.class)); finish(); } } if (blueScoreStr != null) { TeamBlueScore.setText(blueScoreStr); int blueScore = Integer.parseInt(blueScoreStr); if (blueScore == 5) { hasGameEnded = true; reference.removeEventListener(this); startActivity(new Intent(TournamentFinal.this, Blue_win.class)); finish(); } } } @Override public void onCancelled(@NonNull DatabaseError error) { // 可添加错误提示逻辑 } }; reference.addValueEventListener(scoreEventListener); } @Override protected void onDestroy() { super.onDestroy(); if (scoreEventListener != null) { FirebaseDatabase.getInstance().getReference().child("Team_score").removeEventListener(scoreEventListener); } } }
关键修改说明
- 移除定时刷新逻辑:Firebase的
ValueEventListener本身会实时监听数据库变化,无需通过refresh()重复调用fetchdata(),原逻辑会重复添加监听器,导致多次触发跳转和性能浪费。 - 新增游戏结束标记:用
hasGameEnded变量标记游戏状态,一旦某队分数达标,后续数据变化不再处理跳转逻辑。 - 简化数据读取逻辑:移除多余的子节点遍历,直接从
Team_score节点下读取分数字段。 - 跳转后清理资源:触发跳转时主动移除监听器,同时调用
finish()结束当前页面,避免用户返回后再次触发跳转。 - 内存泄漏防护:在
onDestroy()中移除监听器,防止Activity销毁后监听器仍持有引用导致内存泄漏。
除按钮外的刷新方式
- Firebase实时监听(推荐):使用
ValueEventListener/ChildEventListener,数据库数据变化时自动回调,实时同步UI,适合实时性要求高的场景。 - LiveData+ViewModel:将数据包装为LiveData,数据源变化时自动通知UI更新,配合ViewModel可避免配置变更(如屏幕旋转)导致的数据丢失,是Jetpack标准方案。
- 广播接收器:发送自定义广播,在目标页面注册接收器,收到广播时执行刷新逻辑,适合跨页面/组件的通知刷新。
- 内容观察者:针对ContentProvider数据源,注册ContentObserver监听数据变化,自动触发刷新。
- WorkManager:适合低频率、非实时的刷新需求,即使App在后台也能执行任务,不会像Handler定时那样容易被系统杀死。
内容的提问来源于stack exchange,提问作者songju
相关产品推荐
相关产品推荐

