You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Android 调用readRandPosts()时列表未填充致首页帖子不加载

问题根因

代码存在3个核心问题,直接导致首次进入首页无内容:

  • 初始化顺序混乱:你在postAdapter还没实例化、postLists还没初始化的时候,就第一次调用recyclerView.setAdapter(postAdapter)传了空值,属于无效绑定。
  • 异步时序错误:Firebase数据库请求是多层异步执行逻辑,你在外层Video_Posts节点的onDataChange回调里遍历帖子时,又为每个帖子发起了嵌套的关注关系查询,但循环刚跑完、嵌套查询还没返回结果往列表里塞数据,你就直接调用了postAdapter.notifyDataSetChanged(),此时列表是空的,自然渲染不出内容。点击Random按钮能看到内容,是因为点击时距离首次发起请求已经过了一段时间,嵌套的查询已经返回、数据已经缓存到列表里,第二次触发回调时就能正常渲染。
  • 内存泄漏隐患:每次调用readRandPosts()都会新增一个永久存在的ValueEventListener,从未做移除处理,反复点击按钮会重复触发回调,导致数据重复加载。
修复步骤

1. 理顺初始化逻辑

删掉onCreateView里的无效代码,调整初始化顺序,修正后这部分代码如下:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_home, container, false);

    // 删掉这两行无意义的废代码:在当前Fragment里新建HomeFragment实例没有任何作用
    // HomeFragment homeFragment = new HomeFragment();
    // homeFragment.post = post;

    //////////////////////////// recycler view //////////////////////////////
    recyclerView = (VideoPlayerRecyclerView) view.findViewById(R.id.recyclerview);
    LinearLayoutManager layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
    recyclerView.setLayoutManager(layoutManager);
    VerticalSpacingItemDecorator itemDecorator = new VerticalSpacingItemDecorator(0);
    recyclerView.addItemDecoration(itemDecorator);

    // 先初始化列表、适配器,再绑定给RecyclerView,删掉之前重复的setAdapter逻辑
    postLists = new ArrayList<>();
    postAdapter = new PostAdapter(getContext(), postLists);
    recyclerView.setAdapter(postAdapter);

    progressBar = view.findViewById(R.id.progress_circular);
    followingBtn = view.findViewById(R.id.followingBtn);
    randomBtn = view.findViewById(R.id.randomBtn);

    followingBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            checkFollowing();
            Toast.makeText(getContext(), "Following", Toast.LENGTH_SHORT).show();
        }
    });
    randomBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            readRandPosts();
        }
    });

    readRandPosts();
    // 删掉postLists != null的无效判断:你已经手动把postLists初始化成ArrayList,永远不会为null
    return view;
}

2. 修复异步回调时序问题

把嵌套的持续监听改成单次查询,加计数器等所有帖子的关注状态都查询完成、数据全部加入列表后,再刷新UI。同时把监听抽成成员变量方便后续移除,修正后的readRandPosts相关代码:

// 把帖子监听抽成成员变量,避免重复添加
private ValueEventListener postValueEventListener;

private void readRandPosts() {
    progressBar.setVisibility(View.VISIBLE);
    DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Video_Posts");
    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    if (user == null) {
        progressBar.setVisibility(View.GONE);
        Toast.makeText(getContext(), "用户未登录", Toast.LENGTH_SHORT).show();
        return;
    }

    // 先移除旧监听,避免重复回调
    if (postValueEventListener != null) {
        reference.removeEventListener(postValueEventListener);
    }

    postValueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            postLists.clear();
            long totalPostCount = dataSnapshot.getChildrenCount();
            // 计数器记录已完成关注查询的帖子数
            final long[] processedCount = {0};

            for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                Post post = snapshot.getValue(Post.class);
                if (post == null) {
                    processedCount[0]++;
                    checkAndRefresh(processedCount[0], totalPostCount);
                    continue;
                }

                DatabaseReference followRef = FirebaseDatabase.getInstance().getReference("Follow")
                        .child(post.getPublisher())
                        .child("followers")
                        .child(user.getUid());
                // 用单次查询替代持续监听,避免内存泄漏
                followRef.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot followSnapshot) {
                        if (!followSnapshot.exists()) {
                            postLists.add(post);
                        }
                        processedCount[0]++;
                        checkAndRefresh(processedCount[0], totalPostCount);
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {
                        processedCount[0]++;
                        checkAndRefresh(processedCount[0], totalPostCount);
                    }
                });
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            progressBar.setVisibility(View.GONE);
        }
    };
    reference.addValueEventListener(postValueEventListener);
}

// 抽公共方法:所有帖子处理完成后再刷新列表
private void checkAndRefresh(long processed, long total) {
    if (processed == total) {
        Collections.shuffle(postLists);
        postAdapter.notifyDataSetChanged();
        progressBar.setVisibility(View.GONE);
    }
}

3. 补上生命周期监听移除逻辑

在Fragment销毁视图时移除数据库监听,避免内存泄漏和后台空指针:

@Override
public void onDestroyView() {
    super.onDestroyView();
    if (postValueEventListener != null) {
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Video_Posts");
        reference.removeEventListener(postValueEventListener);
    }
}
额外优化提示

删掉原来嵌套查询里的"Nothing to show"Toast,否则列表加载过程中只要遇到已关注用户的帖子就会弹提示,影响使用体验。


内容的提问来源于stack exchange,提问作者user13477176

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 08:39:20