Android接入Firebase拉取数据触发Index:0 Size:0 IndexOutOfBoundsException问题问询
异常触发原因
你遇到的java.lang.IndexOutOfBoundsException: Index: 0, Size: 0错误核心是Firebase Realtime Database的数据拉取为异步操作,和你当前同步执行的跳转逻辑冲突:
- QuizSplash页面初始化时先创建了空的
list,随后注册的Firebase数据监听回调onDataChange不会立刻执行,需要等网络请求完成、云端数据返回后才会触发、往list里填充数据。 - 你注册完监听后立刻执行了页面跳转逻辑,此时还没有拿到云端返回的任何数据,
list还是空集合,跳转后QuestionAnsActivity直接调用list.get(0)自然会触发下标越界错误。 - 本地硬编码测试时数据是同步赋值到
list的,跳转时已经有完整数据,所以不会触发报错。
可行解决方案
方案1(优先采用):数据加载完成后再跳转
修改QuizSplash的逻辑,将页面跳转的代码移到onDataChange回调内部,确保拿到数据后再进入答题页:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_quiz_splash); list = new ArrayList<>(); databaseReference = FirebaseDatabase.getInstance().getReference("Question"); databaseReference.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { list.clear(); for (DataSnapshot dataSnapshot : snapshot.getChildren()) { Questions questions = dataSnapshot.getValue(Questions.class); list.add(questions); } // 校验数据非空后再跳转 if (!list.isEmpty()) { Intent intent = new Intent(QuizSplash.this, QuestionAnsActivity.class); startActivity(intent); finish(); // 可选,关闭启动页避免用户按返回键回到该页 } else { Toast.makeText(QuizSplash.this, "未获取到题目数据", Toast.LENGTH_SHORT).show(); } } @Override public void onCancelled(@NonNull DatabaseError error) { // 异常回调不要留空,提示用户加载失败 Toast.makeText(QuizSplash.this, "题目加载失败:" + error.getMessage(), Toast.LENGTH_SHORT).show(); } }); // 删除原位置的跳转代码 }
方案2(兜底防护):答题页增加空判断
即使做了异步加载跳转的逻辑,也建议在QuestionAnsActivity增加数据校验,避免极端情况崩溃:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.question_ans_activity); // 其他初始化逻辑... // 先校验数据是否合法 if (list == null || list.isEmpty()) { Toast.makeText(this, "题目数据为空,请稍后重试", Toast.LENGTH_SHORT).show(); finish(); return; } allQuestionsList = list; Collections.shuffle(allQuestionsList); questions = list.get(index); // 后续业务逻辑... }
可选优化建议
- 尽量不要用静态变量存储题目列表,容易引发内存泄漏、多页面数据不同步的问题,可通过Intent序列化传递数据,或用ViewModel实现页面间数据共享。
- 启动页可增加加载进度提示,避免用户误以为程序卡住。
内容的提问来源于stack exchange,提问作者Rafi
相关产品推荐
相关产品推荐

