Android:Firebase双应用下Admin端实时获取pelanggaran数据异常
实现管理员端实时获取Pelanggaran数据的方案
咱们先拆解下你现有代码的核心问题,再一步步修改实现实时更新:
现有代码的问题
- 用户列表无法实时更新:你用了
addListenerForSingleValueEvent监听User节点,这只会一次性拉取当前用户数据,后续新增/删除用户不会触发更新。 - 重复监听与内存泄漏风险:每次调用
refreshList()都会为每个用户添加新的addValueEventListener,旧的监听没有被移除,会导致重复接收数据和内存泄漏。 - 适配器更新时机错误:你在
User节点的onDataChange末尾直接创建并设置适配器,但嵌套的Pelanggaran节点监听是异步执行的,这时候pelanggaranList可能还没填充数据,导致列表不显示内容。
修改后的完整代码
下面是修正后的代码,我会在关键部分加注释说明:
// 全局变量:保存每个用户的Pelanggaran监听,用于后续移除避免内存泄漏 private Map<String, ValueEventListener> pelanggaranListeners = new HashMap<>(); private PelanggaranAdapter pelanggaranAdapter; private ArrayList<Pelanggaran> pelanggaranList; private ValueEventListener userValueEventListener; // 保存用户列表监听,用于销毁时移除 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化列表和适配器,只需要一次 pelanggaranList = new ArrayList<>(); pelanggaranAdapter = new PelanggaranAdapter(MainActivity.this, pelanggaranList); recyclerView.setAdapter(pelanggaranAdapter); // 启动实时监听 startRealTimeListeners(); } private void startRealTimeListeners() { DatabaseReference databaseUser = FirebaseDatabase.getInstance().getReference("User"); // 用addValueEventListener替代SingleValueEvent,实时监听用户列表变化 userValueEventListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { // 1. 先清空旧数据和旧监听 pelanggaranList.clear(); removeAllPelanggaranListeners(); // 2. 遍历所有用户,为每个用户的Pelanggaran添加实时监听 for (DataSnapshot dsUser : dataSnapshot.getChildren()) { User user = dsUser.getValue(User.class); if (user == null) continue; // 避免空指针 final String userId = user.getUserId(); DatabaseReference pelanggaranRef = FirebaseDatabase.getInstance().getReference("Pelanggaran").child(userId); ValueEventListener pelanggaranListener = new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot1) { // 先移除该用户的旧数据,避免重复添加 Iterator<Pelanggaran> iterator = pelanggaranList.iterator(); while (iterator.hasNext()) { Pelanggaran p = iterator.next(); if (p.getUserId().equals(userId)) { // 假设Pelanggaran类有getUserId方法 iterator.remove(); } } // 添加该用户的最新Pelanggaran数据 for (DataSnapshot dsPelanggaran : dataSnapshot1.getChildren()) { Pelanggaran pelanggaran = dsPelanggaran.getValue(Pelanggaran.class); if (pelanggaran != null) { pelanggaran.setUserId(userId); // 确保每个Pelanggaran关联正确的用户ID pelanggaranList.add(pelanggaran); } } // 通知适配器数据更新 pelanggaranAdapter.notifyDataSetChanged(); } @Override public void onCancelled(DatabaseError databaseError) { Log.e("PelanggaranListen", "用户" + userId + "的违规数据监听失败", databaseError.toException()); } }; // 保存监听,后续用于移除 pelanggaranListeners.put(userId, pelanggaranListener); pelanggaranRef.addValueEventListener(pelanggaranListener); } } @Override public void onCancelled(DatabaseError databaseError) { Log.e("UserListen", "用户列表监听失败", databaseError.toException()); } }; databaseUser.addValueEventListener(userValueEventListener); } // 移除所有Pelanggaran节点的监听,避免内存泄漏 private void removeAllPelanggaranListeners() { for (Map.Entry<String, ValueEventListener> entry : pelanggaranListeners.entrySet()) { DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Pelanggaran").child(entry.getKey()); ref.removeEventListener(entry.getValue()); } pelanggaranListeners.clear(); } // 在Activity销毁时移除所有监听,彻底避免内存泄漏 @Override protected void onDestroy() { super.onDestroy(); removeAllPelanggaranListeners(); if (userValueEventListener != null) { FirebaseDatabase.getInstance().getReference("User").removeEventListener(userValueEventListener); } }
关键修改说明
- 全局适配器初始化:只在
onCreate里初始化一次适配器,后续只更新数据并通知适配器,避免重复创建。 - 实时监听用户列表:用
addValueEventListener监听User节点,用户新增/删除时都会触发onDataChange。 - 管理Pelanggaran监听:用
HashMap保存每个用户的监听,在用户列表变化时先移除旧监听,再添加新的,避免重复监听。 - 数据去重与更新:每次获取某个用户的Pelanggaran数据时,先移除该用户的旧数据,再添加新数据,避免列表重复。
- 内存泄漏防护:在
onDestroy里移除所有监听,确保Activity销毁时没有残留的Firebase监听。
额外建议
如果你的业务允许,也可以考虑优化Firebase数据结构,比如在根节点下新增一个AllPelanggaran节点,每次用户端新增Pelanggaran时,同时写入Pelanggaran/{userId}和AllPelanggaran,这样管理员端只需要监听AllPelanggaran一个节点,就能实时获取所有数据,不需要遍历所有用户,性能会更好。
内容的提问来源于stack exchange,提问作者Ivana Natalia
相关产品推荐
相关产品推荐

