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

Android AsyncTask 完整解析:從網絡下載圖片到 UI 更新

     編輯:程式設計疑難解答

AsyncTask 泛型參數詳解

AsyncTask<String, Void, Bitmap> 三個類型參數含義:

  • Params (String):doInBackground 輸入參數類型,此處為圖片 URL 字符串。
  • Progress (Void):進度更新類型,此處無進度回調。
  • Result (Bitmap):後台任務返回結果類型,也是 onPostExecute 參數類型。

核心流程與代碼實現

public class ImageDownloadTask extends AsyncTask<String, Void, Bitmap> {
    private WeakReference<ImageView> imageViewRef;
    private ProgressDialog dialog;

    public ImageDownloadTask(ImageView imageView, Context context) {
        this.imageViewRef = new WeakReference<>(imageView);
        this.dialog = new ProgressDialog(context);
    }

    @Override
    protected void onPreExecute() {
        dialog.setMessage("圖片加載中...");
        dialog.show();
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        String urlStr = params[0];
        try {
            URL url = new URL(urlStr);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(10000);
            conn.setRequestMethod("GET");
            
            if (conn.getResponseCode() == 200) {
                InputStream is = conn.getInputStream();
                return BitmapFactory.decodeStream(is);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        dialog.dismiss();
        if (bitmap != null && imageViewRef.get() != null) {
            imageViewRef.get().setImageBitmap(bitmap);
        }
    }
}

關鍵最佳實踐

1. 使用 WeakReference 防止內存洩漏

Activity 銷毀時,AsyncTask 可能仍在運行。持有 WeakReference<ImageView> 避免阻礙 GC 回收 Activity。

2. 取消任務處理

// 在 Activity onDestroy 中
if (task != null && task.getStatus() == AsyncTask.Status.RUNNING) {
    task.cancel(true); // 中斷網絡請求需在 doInBackground 檢查 isCancelled()
}

3. 線程池與並發控制

預設為串行執行(SerialExecutor)。若需並行下載多張圖:

task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url1, url2);

現代替代方案

Google 已在 Android 11 (API 30) 標記 AsyncTask 為過時。推薦使用:

  • Kotlin Coroutines + Flow:結構化併發,生命周期感知。
  • RxJava:強大的操作符鏈。
  • Glide / Picasso / Coil:成熟圖片加載框架,自動處理緩存、生命周期、併發。

總結

AsyncTask 適合簡單、短暫的後台任務。掌握其生命周期(onPreExecute → doInBackground → onPostExecute)、泛型含義及內存洩漏防範,是 Android 進階的基礎。新項目請優先選用現代異步框架。

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