目录
[1. 基础线程(Thread)](#1. 基础线程(Thread))
[2. Handler 与 Looper](#2. Handler 与 Looper)
[3. AsyncTask(已废弃,仅作了解)](#3. AsyncTask(已废弃,仅作了解))
[4. ExecutorService(线程池)](#4. ExecutorService(线程池))
[5. IntentService(已废弃,推荐 WorkManager)](#5. IntentService(已废弃,推荐 WorkManager))
[6. Kotlin 协程(Coroutines,现代推荐方案)](#6. Kotlin 协程(Coroutines,现代推荐方案))
[7. HandlerThread](#7. HandlerThread)
在 Android 中,实现多线程编程主要有以下几种方式,每种方式都有其适用场景和优缺点。
1. 基础线程(Thread)
原理
通过 Java 的 Thread
类直接创建并启动线程,适用于简单的异步任务。
示例
java
new Thread(new Runnable() {
@Override
public void run() {
// 子线程执行耗时任务(如网络请求)
// 注意:不能直接在此更新 UI!
runOnUiThread(() -> {
textView.setText("任务完成"); // 切换到主线程更新 UI
});
}
}).start();
// Kotlin 简化写法
Thread {
// 子线程任务
runOnUiThread { textView.text = "任务完成" }
}.start()
缺点
-
手动管理复杂:线程数量过多时难以控制。
-
无法直接更新 UI :必须通过
runOnUiThread
或Handler
切回主线程。
2. Handler 与 Looper
原理
通过 Handler
和 Looper
实现线程间通信,适用于需要频繁在主线程更新 UI 的场景。
示例
java
// 主线程创建 Handler
Handler mainHandler = new Handler(Looper.getMainLooper());
new Thread(() -> {
// 子线程执行任务
mainHandler.post(() -> {
textView.setText("通过 Handler 更新 UI");
});
}).start();
扩展:子线程创建消息循环
java
// 子线程初始化 Looper
class WorkerThread extends Thread {
private Handler workerHandler;
@Override
public void run() {
Looper.prepare(); // 创建 Looper
workerHandler = new Handler(Looper.myLooper()) {
@Override
public void handleMessage(Message msg) {
// 处理子线程收到的消息
}
};
Looper.loop(); // 启动消息循环
}
}
优点
-
灵活控制线程通信:支持延迟消息、消息队列管理。
-
主线程安全更新 UI。
3. AsyncTask(已废弃,仅作了解)
原理
Android 早期提供的异步任务工具,内部封装了线程切换逻辑。
示例
java
private class MyAsyncTask extends AsyncTask<Void, Integer, String> {
@Override
protected String doInBackground(Void... voids) {
// 子线程执行耗时任务
publishProgress(50); // 更新进度
return "结果";
}
@Override
protected void onProgressUpdate(Integer... values) {
// 主线程更新进度条
progressBar.setProgress(values[0]);
}
@Override
protected void onPostExecute(String result) {
// 主线程处理结果
textView.setText(result);
}
}
// 启动任务
new MyAsyncTask().execute();
缺点
-
内存泄漏风险:若 AsyncTask 持有 Activity 引用,可能导致无法回收。
-
API 30+ 已废弃 :推荐使用协程或
ExecutorService
。
4. ExecutorService(线程池)
原理
Java 并发框架提供的线程池管理,适合需要控制并发数量的场景。
示例
java
// 创建固定大小的线程池
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.execute(() -> {
// 子线程执行任务
runOnUiThread(() -> textView.setText("任务完成"));
});
// 关闭线程池(通常在 onDestroy 中调用)
executor.shutdown();
优点
-
资源复用:避免频繁创建/销毁线程的开销。
-
任务队列管理 :支持提交
Runnable
或Callable
任务。
5. IntentService(已废弃,推荐 WorkManager)
原理
继承自 Service
,内部通过 HandlerThread 处理异步任务,适合后台执行独立任务。
示例
java
public class MyIntentService extends IntentService {
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
// 子线程执行任务(如文件下载)
// 无需手动停止,任务完成后自动销毁
}
}
// 启动服务
Intent intent = new Intent(context, MyIntentService.class);
startService(intent);
缺点
- Android 8.0+ 限制后台服务 :需改用
WorkManager
或JobScheduler
。
6. Kotlin 协程(Coroutines,现代推荐方案)
原理
通过挂起函数(Suspend Function)实现非阻塞异步操作,简化回调地狱。
示例
Kotlin
// ViewModel 中使用协程
class MyViewModel : ViewModel() {
fun fetchData() {
viewModelScope.launch(Dispatchers.IO) { // 切换到 IO 线程
val result = apiService.getData() // 网络请求
withContext(Dispatchers.Main) { // 切回主线程
textView.text = result
}
}
}
}
// 并发任务处理
viewModelScope.launch {
val deferred1 = async { fetchData1() } // 启动异步任务1
val deferred2 = async { fetchData2() } // 启动异步任务2
val result1 = deferred1.await() // 等待任务1完成
val result2 = deferred2.await() // 等待任务2完成
showResult(result1 + result2) // 合并结果
}
优点
-
代码简洁:用同步写法实现异步逻辑。
-
生命周期感知 :自动绑定到
ViewModel
或Activity
生命周期。 -
灵活调度 :通过
Dispatchers.Main/IO/Default
指定线程。
7. HandlerThread
原理
结合 Thread
和 Looper
,适用于需要长时间运行的子线程任务。
示例
java
HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
handler.post(() -> {
// 在 HandlerThread 中执行任务
});
// 销毁时释放资源
handlerThread.quit();
对比总结
方式 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
Thread | 简单异步任务 | 直接易用 | 手动管理复杂,无法直接更新 UI |
Handler | 主线程通信 | 灵活控制消息队列 | 代码冗余 |
AsyncTask | 旧项目简单任务(已废弃) | 自动线程切换 | 内存泄漏风险,API 废弃 |
Executor | 线程池管理 | 资源复用,任务队列管理 | 需手动切换主线程 |
IntentService | 后台独立任务(已废弃) | 自动销毁 | 受系统限制,替代方案更优 |
协程 | 现代异步编程 | 代码简洁,生命周期感知 | 需学习 Kotlin 语法 |
HandlerThread | 需要 Looper 的子线程任务 | 自带消息循环 | 需手动退出 |
最佳实践建议
-
简单任务 :使用
Thread
+Handler
或runOnUiThread
。 -
复杂并发 :优先选择 协程 (配合
viewModelScope
或lifecycleScope
)。 -
线程池管理 :使用
ExecutorService
控制并发数量。 -
后台持久任务 :采用
WorkManager
(兼容不同 API 版本)。
通过合理选择多线程方案,可显著提升 App 的响应速度和用户体验,同时避免 ANR(Application Not Responding)问题。