Fragment与Fragment、Activity通信的方式?
更多面试题请看这里:https://interview.raoyunsoft.com/
在Android开发中,Fragment之间的通信以及与宿主Activity的交互是核心技能。以下是几种主流实现方式,每种方式都有其适用场景和注意事项:
1. 直接调用Fragment方法
实现原理:
通过FragmentManager
获取目标Fragment实例,直接调用其public方法。
代码示例:
// 在FragmentA中调用FragmentB的方法
val fragmentB = requireActivity().supportFragmentManager.findFragmentById(R.id.fragment_container) as FragmentB
fragmentB.updateData("New Data")
适用场景:
- 简单场景下的兄弟Fragment通信
- 目标Fragment已通过XML布局固定嵌入
注意事项:
⚠️ 强依赖Fragment ID或Tag,需确保Fragment已添加到容器
⚠️ 破坏封装性,耦合度高
2. 接口回调(推荐方式)
实现原理:
- Fragment定义通信接口
- Activity实现该接口
- Fragment通过
onAttach()
获取接口实例
完整流程:
// 1. Fragment中定义接口
class MyFragment : Fragment() {interface DataListener {fun onDataReceived(data: String)}private var listener: DataListener? = null// 2. 绑定接口实现override fun onAttach(context: Context) {super.onAttach(context)listener = context as? DataListener ?: throw ClassCastException()}// 3. 触发回调private fun sendData() {listener?.onDataReceived("Hello from Fragment!")}
}// 4. Activity实现接口
class HostActivity : AppCompatActivity(), MyFragment.DataListener {override fun onDataReceived(data: String) {// 处理数据(可转发给其他Fragment)}
}
优势:
✅ 解耦设计,符合面向接口编程原则
✅ 支持一对多通信(Activity可中转数据)
✅ Google官方推荐方式
3. 广播机制
实现方式:
// 发送广播(Fragment/Activity中)
val intent = Intent("CUSTOM_ACTION").apply {putExtra("key", "broadcast data")
}
requireActivity().sendBroadcast(intent)// 接收广播(需注册BroadcastReceiver)
private val receiver = object : BroadcastReceiver() {override fun onReceive(context: Context?, intent: Intent?) {intent?.getStringExtra("key")?.let { handleData(it) }}
}// 注册/注销
override fun onStart() {super.onStart()requireActivity().registerReceiver(receiver, IntentFilter("CUSTOM_ACTION"))
}override fun onStop() {super.onStop()requireActivity().unregisterReceiver(receiver)
}
适用场景:
- 跨进程通信需求
- 全局事件通知(如登录状态变更)
缺点:
❌ 性能开销较大
❌ 需要手动管理生命周期
❌ 类型安全弱
4. Fragment调用Activity方法
实现方式:
// Fragment中
(requireActivity() as HostActivity).handleFragmentData("data")// Activity中
class HostActivity : AppCompatActivity() {// 暴露public方法fun handleFragmentData(data: String) {// 处理数据或转发}
}
最佳实践:
- 优先通过接口抽象(方式2)而非直接强转
- 若需直接调用,建议添加空安全检查:
(requireActivity() as? HostActivity)?.handleFragmentData("data")
现代方案补充
ViewModel + LiveData(官方推荐替代方案):
// 共享ViewModel
class SharedViewModel : ViewModel() {val data = MutableLiveData<String>()
}// Activity中初始化
val viewModel by viewModels<SharedViewModel>()// FragmentA发送数据
viewModel.data.value = "New value"// FragmentB观察数据
viewModel.data.observe(viewLifecycleOwner) { value ->// 响应数据变化
}
优势:
✅ 生命周期感知,自动清理资源
✅ 数据驱动UI更新
✅ 彻底解耦通信方
选择建议:
- 简单通信 → 接口回调
- 数据共享 → ViewModel + LiveData
- 全局事件 → 广播(优先考虑LocalBroadcastManager)
- 避免直接方法调用(高耦合方案)