首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 異步查詢多個 URL 存入數組崩潰:用 List 替代定長數組

     編輯:程式設計綜合問答

崩潰代碼

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/越界
        }
    });
}

核心問題

  1. 數組長度固定:String[] 必須在創建時指定長度,動態添加不可行。
  2. 異步回調中訪問循環變量 i:回調執行時循環已結束,i == 10,導致越界或覆蓋同一位置。
  3. 未初始化數組:null 賦值直接 NPE。

正確方案:ArrayList + final 局部變量

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,異步回調捕獲最終變量,併發用同步容器或協程流控制。**

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved