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

Android 非同步載入網路圖片動態生成 ImageView:主執行緒更新 UI 的正確姿勢

     編輯:程式設計疑難解答

錯誤現象

在 Thread.run() 中直接 linearLayout.addView(imageView) 導致 ViewRootImpl$CalledFromWrongThreadException,且 gURL 陣列因異步未填充而為 null。

核心問題

  1. 網路請求與 UI 操作執行緒混淆:Android 禁止非主執行緒操作 View。
  2. 異步回調順序錯誤:for 迴圈在網路回調完成前執行,gURL[i] 尚未賦值。

修正方案:runOnUiThread / Handler / Glide/Picasso

方案一:runOnUiThread(最小改動)

// 在網路回調成功後
runOnUiThread(() -> {
    for (int i = 0; i < gURL.length; i++) {
        if (gURL[i] != null) {
            ImageView iv = new ImageView(MainActivity.this);
            // 建議使用圖片載入庫,此處示範同步下載(僅教學)
            new Thread(() -> {
                Bitmap bmp = downloadBitmap(gURL[i]);
                runOnUiThread(() -> iv.setImageBitmap(bmp));
            }).start();
            linearLayout.addView(iv);
        }
    }
});

方案二:使用 Glide(推薦生產)

// build.gradle
implementation 'com.github.bumptech.glide:glide:4.16.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.16.0'

// Activity 中
for (String url : gURL) {
    if (url != null) {
        ImageView iv = new ImageView(this);
        linearLayout.addView(iv);
        Glide.with(this).load(url).into(iv); // 自動處理執行緒、快取、佔位圖
    }
}

關鍵點總結

  • 網路請求放入子執行緒(或用 OkHttp/Retrofit 異步回調)。
  • **所有 View 操作必須在主執行緒**(runOnUiThread、Handler、View.post、Activity.runOnUiThread)。
  • 動態生成大量 ImageView 考慮使用 RecyclerView + GridLayoutManager,避免 OOM。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved