# AsyncTask

## 目录
- [AsyncTask原理](#asynctask原理)
- [AsyncTask生命周期](#asynctask生命周期)
- [AsyncTask执行流程](#asynctask执行流程)
- [AsyncTask问题](#asynctask问题)
- [AsyncTask替代方案](#asynctask替代方案)
- [AsyncTask最佳实践](#asynctask最佳实践)
- [面试常见问题](#面试常见问题)

---

## AsyncTask原理

### AsyncTask 简介

```java
// AsyncTask：异步任务类
// 在后台线程执行任务，在主线程更新 UI
// 已废弃（Android 11+），推荐使用协程或 ExecutorService
```

### AsyncTask 结构

```java
public abstract class AsyncTask<Params, Progress, Result> {
    // Params：参数类型
    // Progress：进度类型
    // Result：结果类型
    
    // 在后台线程执行
    protected abstract Result doInBackground(Params... params);
    
    // 在主线程执行（任务开始前）
    protected void onPreExecute() { }
    
    // 在主线程执行（进度更新）
    protected void onProgressUpdate(Progress... values) { }
    
    // 在主线程执行（任务完成后）
    protected void onPostExecute(Result result) { }
}
```

---

## AsyncTask生命周期

### 生命周期方法

```java
public class MyAsyncTask extends AsyncTask<String, Integer, String> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // 主线程：任务开始前
    }
    
    @Override
    protected String doInBackground(String... params) {
        // 后台线程：执行任务
        for (int i = 0; i < 100; i++) {
            publishProgress(i); // 更新进度
        }
        return "Result";
    }
    
    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        // 主线程：进度更新
        int progress = values[0];
        progressBar.setProgress(progress);
    }
    
    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        // 主线程：任务完成
        textView.setText(result);
    }
    
    @Override
    protected void onCancelled() {
        super.onCancelled();
        // 主线程：任务取消
    }
}
```

---

## AsyncTask执行流程

### 执行流程

```
1. execute() → 创建任务
2. onPreExecute() → 主线程执行
3. doInBackground() → 后台线程执行
4. publishProgress() → 更新进度
5. onProgressUpdate() → 主线程更新 UI
6. onPostExecute() → 主线程执行（任务完成）
```

### 执行示例

```java
// 创建并执行
MyAsyncTask task = new MyAsyncTask();
task.execute("param1", "param2");

// 取消任务
task.cancel(true);
```

---

## AsyncTask问题

### 1. 内存泄漏

```java
// ❌ 问题：AsyncTask 持有 Activity 引用
public class MainActivity extends AppCompatActivity {
    private MyAsyncTask task;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        task = new MyAsyncTask();
        task.execute();
    }
    
    // 如果 Activity 销毁，但 AsyncTask 还在执行
    // Activity 无法被回收
}
```

### 2. 配置变更问题

```java
// ❌ 问题：屏幕旋转时 Activity 重建
// AsyncTask 持有旧 Activity 引用
// 可能导致崩溃或内存泄漏
```

### 3. 串行执行

```java
// AsyncTask 默认串行执行
// 多个 AsyncTask 按顺序执行
// 可能影响性能
```

### 4. 已废弃

```java
// Android 11+ 已废弃 AsyncTask
// 推荐使用协程或 ExecutorService
```

---

## AsyncTask替代方案

### 方案1：协程（推荐）

```kotlin
// 使用协程
lifecycleScope.launch {
    val result = withContext(Dispatchers.IO) {
        // 后台执行
        loadData()
    }
    // 主线程更新 UI
    updateUI(result)
}
```

### 方案2：ExecutorService

```java
// 使用线程池
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(() -> {
    // 后台执行
    String result = loadData();
    
    // 主线程更新 UI
    runOnUiThread(() -> {
        updateUI(result);
    });
});
```

### 方案3：RxJava

```java
// 使用 RxJava
Observable.fromCallable(() -> loadData())
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(result -> {
        updateUI(result);
    });
```

---

## AsyncTask最佳实践

### 1. 使用静态内部类

```java
// ✅ 使用静态内部类避免内存泄漏
private static class MyAsyncTask extends AsyncTask<String, Void, String> {
    private WeakReference<MainActivity> activity;
    
    MyAsyncTask(MainActivity activity) {
        this.activity = new WeakReference<>(activity);
    }
    
    @Override
    protected String doInBackground(String... params) {
        // 执行任务
        return null;
    }
    
    @Override
    protected void onPostExecute(String result) {
        MainActivity act = activity.get();
        if (act != null && !act.isFinishing()) {
            // 更新 UI
        }
    }
}
```

### 2. 及时取消

```java
@Override
protected void onDestroy() {
    super.onDestroy();
    if (task != null) {
        task.cancel(true);
    }
}
```

### 3. 使用替代方案

```java
// 推荐使用协程或 ExecutorService
// AsyncTask 已废弃
```

---

## 面试常见问题

### Q1: AsyncTask 的原理？

**答案：**
- 在后台线程执行任务（doInBackground）
- 在主线程更新 UI（onPostExecute、onProgressUpdate）
- 使用线程池执行任务

### Q2: AsyncTask 的问题？

**答案：**
1. 内存泄漏：持有 Activity 引用
2. 配置变更：屏幕旋转时可能出问题
3. 串行执行：默认串行，可能影响性能
4. 已废弃：Android 11+ 已废弃

### Q3: AsyncTask 的替代方案？

**答案：**
1. **协程**：Kotlin 官方推荐
2. **ExecutorService**：线程池
3. **RxJava**：响应式编程

### Q4: 如何避免 AsyncTask 内存泄漏？

**答案：**
1. 使用静态内部类
2. 使用 WeakReference
3. 及时取消任务
4. 使用替代方案

---

*最后更新：2024年*
