悠悠楠杉
子Activity如何优雅访问父Activity的数据与方法?5种实战方案详解
子Activity如何优雅访问父Activity的数据与方法?5种实战方案详解
在Android开发中,Activity间的数据交互是高频需求场景。当我们需要从子Activity反向调用父Activity资源时,如何实现既安全又解耦的通信?本文将深入剖析五种主流方案,并附上防坑指南。
一、为何需要反向通信?
常见场景包括:
- 修改父Activity的UI状态(如更新标题栏)
- 回调用户选择结果(如日期选择器)
- 同步数据变更(如购物车数量刷新)
- 触发父级业务逻辑(如支付结果通知)
若处理不当会导致:
java
// 典型错误示范:直接强转获取Activity
MainActivity parent = (MainActivity) getActivity();
parent.updateData(); // 可能引发ClassCastException
二、五大核心解决方案对比
方案1:接口回调(推荐做法)
优点:完全解耦、类型安全kotlin
// 1. 定义通信接口
interface DataCallback {
fun onDataUpdated(newData: String)
}
// 2. 父Activity实现接口
class ParentActivity : AppCompatActivity(), DataCallback {
override fun onDataUpdated(newData: String) {
textView.text = newData
}
}
// 3. 子Activity中调用
(childActivity as? DataCallback)?.onDataUpdated("最新数据")
方案2:ViewModel共享(AndroidX方案)
适合需要持久化数据的场景:kotlin
// 共享ViewModel
class SharedVM : ViewModel() {
val liveData = MutableLiveData
}
// 父Activity中
val vm = ViewModelProvider(this).get(SharedVM::class.java)
vm.liveData.observe(this) { data ->
// 更新UI
}
// 子Activity中
val parentVm = ViewModelProvider(requireActivity()).get(SharedVM::class.java)
parentVm.liveData.value = "新数据"
方案3:Result API(Activity 1.3+)
官方推荐的启动方式:kotlin
// 启动子Activity
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
val data = result.data?.getStringExtra("key")
}
}.launch(intent)
// 子Activity返回数据
setResult(RESULT_OK, Intent().apply {
putExtra("key", "返回值")
})
finish()
方案4:EventBus(第三方方案)
适合全局事件通知:
gradle
// build.gradle
implementation 'org.greenrobot:eventbus:3.3.1'
java
// 父Activity中注册
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(UpdateEvent event) {
// 处理事件
}
// 子Activity发送事件
EventBus.getDefault().post(new UpdateEvent("数据"));
方案5:静态变量(应急方案)
慎用场景:临时调试、简单DEMOjava
class ParentActivity {
companion object {
var instance: ParentActivity? = null
}
override fun onCreate() {
super.onCreate()
instance = this
}
}
// 子Activity中访问
ParentActivity.instance?.updateData()
三、避坑指南
- 内存泄漏预防
- 及时注销EventBus订阅
- 弱引用持有Activity实例kotlin
class SafeCallback(activity: ParentActivity) {
private val weakRef = WeakReference(activity)
fun update() {
weakRef.get()?.updateUI()
}
}
- 生命周期安全
- 检查isFinishing状态
- 使用LiveData自动感知生命周期
- 类型转换安全
kotlin (activity as? MainActivity)?.method() ?: run { Log.e("TAG", "类型转换失败") }
四、最佳实践建议
- 简单数据传递 → Result API
- 复杂业务交互 → 接口回调
- 跨组件通信 → ViewModel + LiveData
- 全局事件 → EventBus(需做好管理)
代码规范建议:
- 接口命名统一添加Callback
后缀
- ViewModel按功能模块划分
- 事件类使用Event
结尾命名
- 重要通信添加Log日志
掌握这些技巧后,Activity间的通信将变得优雅而可靠。根据具体业务场景选择合适方案,能显著提升代码可维护性。