# 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:结果类型 // 在后台线程执行 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 { @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 { private WeakReference 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年*