Android中的跨线程通信主要通过以下几种机制实现:
1. Handler-Looper-MessageQueue机制
这是Android最基础的线程通信方案。主线程默认持有Looper,子线程通过Handler向主线程的MessageQueue发送Message。Looper循环取出消息后,由Handler的`handleMessage()`处理。关键点:
- 子线程需调用`Looper.prepare()`和`Looper.loop()`才能创建消息循环
- 通过`HandlerThread`可快速创建带Looper的子线程
- 注意内存泄漏风险(Handler持有Activity引用时需用WeakReference)
2. AsyncTask(已废弃)
虽已废弃但需了解原理:通过内部Handler将`doInBackground()`的子线程结果切换到主线程的`onPostExecute()`。缺点包括Activity销毁时任务丢失、并发管理问题等。
3. RxJava响应式编程
使用`subscribeOn`和`observeOn`操作符显式指定线程切换:
java
Observable.just(data)
.subscribeOn(Schedulers.io()) // 子线程执行
.observeOn(AndroidSchedulers.mainThread()) // 主线程回调
.subscribe(...);
优势在于链式调用和强大的错误处理能力。
4. LiveData(推荐)
ViewModel层持有LiveData,Observer在UI线程自动接收数据更新:
- 内置生命周期感知,避免内存泄漏
- 通过`postValue()`从子线程触发UI更新
- 配合Room数据库时可自动异步查询
5. Kotlin协程
CoroutineContext指定Dispatchers切换线程:
kotlin
lifecycleScope.launch(Dispatchers.IO) {
val data = fetchData() // IO线程
withContext(Dispatchers.Main) {
updateUI(data) // 主线程
}
}
结构化并发机制比回调更简洁。
6. EventBus
发布-订阅模式的库,通过`@Subscribe(threadMode = ThreadMode.MAIN)`注解自动切换线程。需注意妥善处理事件粘性和注销。
7. BroadcastReceiver
系统级跨进程通信方案,通过Intent广播。建议使用LocalBroadcastManager限于应用内通信。
8. 共享内存+同步锁
直接共享对象时需使用:
- `synchronized`关键字
- `volatile`保证可见性
- `AtomicInteger`等原子类
需谨慎避免死锁和性能问题。
9. 跨进程方案
涉及多进程时需用:
- AIDL(接口定义语言)
- Messenger(基于Binder的轻量级方案)
- ContentProvider
10. WorkManager
后台任务调度框架,自动处理线程切换和任务链,适合延迟执行或周期任务。
特殊场景处理建议:
大量数据传递优先使用`Parcelable`代替`Serializable`提升性能
高频率更新考虑Choreographer同步VSYNC信号
避免在子线程直接更新View(即便检查了`View.post()`也可能引发竞争条件)
选择方案时需权衡:开发效率(如协程)、性能(如Handler)、维护成本(如LiveData)。现代架构推荐组合使用ViewModel+LiveData+协程。