String Image_url[] = null; // 定長數組,長度未知
for (i = 0; i < 10; i++) {
query.findObjects(..., new FindListener() {
onSuccess(List list) {
String url = list.get(0).getPicture().getFileUrl(...);
Image_url[i] = url; // i 可能已變為 10,且數組未初始化長度 → NPE/越界
}
});
}
String[] 必須在創建時指定長度,動態添加不可行。i == 10,導致越界或覆蓋同一位置。null 賦值直接 NPE。List imageUrls = new ArrayList<>(); // 動態擴容
for (int k = 1; k <= 10; k++) {
final int index = k; // 捕獲當前值
BmobQuery query = new BmobQuery<>();
query.addWhereEqualTo("id", index);
query.findObjects(this, new FindListener() {
@Override
public void onSuccess(List list) {
String url = list.get(0).getPicture().getFileUrl(MainActivity.this);
imageUrls.add(url); // 線程安全?Bmob 回調在主線程,ArrayList 非線程安全但單線程無問題
// 若需順序,可用 imageUrls.add(index - 1, url) 但需預填 null
}
@Override public void onError(int code, String msg) { Log.e("TAG", msg); }
});
}
// 方案 A:CountDownLatch 等待所有完成
CountDownLatch latch = new CountDownLatch(10);
List urls = Collections.synchronizedList(new ArrayList<>(Collections.nCopies(10, null)));
for (int k = 1; k <= 10; k++) {
final int pos = k - 1;
query.findObjects(..., new FindListener() {
onSuccess(list) { urls.set(pos, list.get(0).getPicture().getFileUrl(...)); latch.countDown(); }
onError(...) { latch.countDown(); }
});
}
latch.await(); // 主線程等待(不能在 UI 線程!需放後台線程或用 RxJava/Flow 串聯)
**結論:動態集合用 List,異步回調捕獲最終變量,併發用同步容器或協程流控制。**