Java(Android)中Firestore值存入ArrayList后操作应用崩溃如何解决
崩溃原因
核心问题是数组索引越界,你的代码存在以下逻辑错误:
- 你在遍历Firestore返回结果前就固定生成了0~3的随机数
randomPicker,但numberPot是在遍历过程中逐个填充元素的:比如第一次遍历后numberPot只有1个元素,此时你调用numberPot.get(randomPicker)如果随机到大于等于1的索引,直接触发越界崩溃。 - 你把随机取值、匹配文档、更新字段的逻辑全写在了遍历循环内部,会重复执行多次不必要的查询,且内部更新逻辑使用的是外层循环的
document对象,更新的根本不是你匹配到的对应GameCode的文档,逻辑完全错误。 - 未对
document.get("GameCode")的返回值做类型校验,要是字段值不是int类型也会触发类型转换异常。
修复后代码
GamePortals.get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull @NotNull Task<QuerySnapshot> task) { if (task.isSuccessful() && task.getResult() != null){ ArrayList<Integer> numberPot = new ArrayList<>(); // 先把所有GameCode存入数组 for (QueryDocumentSnapshot document: task.getResult()){ Object gameCodeVal = document.get("GameCode"); if (gameCodeVal instanceof Integer) { numberPot.add((Integer) gameCodeVal); } } // 数组非空后再生成随机索引 if (numberPot.size() == 0) { Toast.makeText(getApplicationContext(),"没有可用的GameCode", Toast.LENGTH_SHORT).show(); return; } int randomPicker = (int) (Math.random() * numberPot.size()); Integer targetGameCode = numberPot.get(randomPicker); displayData.setText(String.valueOf(targetGameCode)); // 匹配对应GameCode的文档更新字段 GamePortals.whereEqualTo("GameCode", targetGameCode) .get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull @NotNull Task<QuerySnapshot> task) { if (task.isSuccessful() && !task.getResult().isEmpty()){ QueryDocumentSnapshot targetDoc = task.getResult().getDocuments().get(0); targetDoc.getReference().update("GameState","Winner"); Toast.makeText(getApplicationContext(),"更新成功!", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(getApplicationContext(),"更新失败,未找到对应文档", Toast.LENGTH_SHORT).show(); } } }); }else{ Toast.makeText(getApplicationContext(),"查询出错", Toast.LENGTH_SHORT).show(); } } });
内容的提问来源于stack exchange,提问作者solomon albert
相关产品推荐
相关产品推荐

