Firebase代码未按逐行逻辑执行,数据填充晚于Fragment初始化问题
问题根源
Firebase Realtime Database的读写操作是异步回调执行的,你调用addListenerForSingleValueEvent只是向Firebase提交了一个数据请求,主线程不会阻塞等待请求返回,而是会直接执行后面的selectedFragment = new CurrentPlaylistFragment(x)代码,这时候Playlist的songs、image_id等字段还没被赋值,等后续网络请求成功回调onDataChange时,Fragment已经创建完成了,自然就出现了数据填充晚于Fragment加载的问题。
修正方案
把Fragment的初始化和切换逻辑,移动到onDataChange回调的末尾,确保所有数据都填充到Playlist对象后,再创建Fragment:
Playlist x = new Playlist (0,"0","1988", true); x.setTitle("Spokojnie"); x.setDescription("Kult"); mAuth = FirebaseAuth.getInstance(); database = FirebaseDatabase.getInstance(); database_ref = database.getReference(); final String[] album_array = new String[1]; final String[] author_array = new String[1]; ArrayList<Song> songs = new ArrayList<>(); if (mAuth.getCurrentUser() != null) { database_ref.child("music").child("albums").child("Kult").child("Spokojnie").child("songs").addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { album_array[0] = snapshot.getRef().getParent().getKey(); author_array[0] = snapshot.getRef().getParent().getParent().getKey(); for (DataSnapshot ds: snapshot.getChildren()){ System.out.println(ds.getKey().toString()); Song local_song = new Song(0, author_array[0], album_array[0], ds.getKey().toString(),Uri.parse(ds.getValue().toString())); songs.add(local_song); } x.setSongs(songs); x.setImage_id(snapshot.child("image_id").getValue().toString()); // 数据加载完成后再初始化、切换Fragment selectedFragment = new CurrentPlaylistFragment(x); // 此处补充你原本切换Fragment的业务代码即可 } @Override public void onCancelled(@NonNull DatabaseError error) { // 建议补充异常处理逻辑,比如加载失败给用户提示 } }); }
补充注意点
- 如果需要优化体验,可在发起Firebase请求前先显示加载弹窗,回调完成后再关闭弹窗切换Fragment
- 不要忽略
onCancelled回调,可在该方法内处理请求失败的场景,避免无响应的情况 - 如果当前页面可能在请求返回前就销毁,要在页面销毁回调里移除Firebase的监听器,避免内存泄漏
内容的提问来源于stack exchange,提问作者fariji1294
相关产品推荐
相关产品推荐

