Fragment与Activity的5种通信方式

3 阅读2分钟

1. 接口回调 (官方推荐)

实现方式

  • 在 Fragment 中定义接口,Activity 实现该接口。
  • Fragment 通过 onAttach() 获取 Activity 的接口实例并调用方法。
// Fragment 定义接口
public interface OnMessageListener {
    void onMessageReceived(String message);
}

// Activity 实现接口
public class MainActivity implements OnMessageListener {
    @Override
    void onMessageReceived(String message) {
        // 处理消息
    }
}

// Fragment 中调用
OnMessageListener listener = (OnMessageListener) getActivity();
listener.onMessageReceived("Hello Activity!");

优点

  • 类型安全,解耦性强。
    缺点
  • 需要手动绑定接口。

2. ViewModel + LiveData (架构组件)

实现方式

  • 使用 ViewModel 共享数据,通过 LiveData 观察数据变化。
// SharedViewModel.kt
class SharedViewModel : ViewModel() {
    val message = MutableLiveData<String>()
}

// Activity 中观察
viewModel.message.observe(this) { msg ->
    // 处理消息
}

// Fragment 中发送
viewModel.message.value = "Hello Activity!"

优点

  • 生命周期感知,适合复杂数据共享。
    缺点
  • 需要引入 Android 架构组件。

3. EventBus (第三方库)

实现方式

  • 使用事件总线库(如 EventBus)发布/订阅事件。
// 定义事件类
public class MessageEvent {
    String message;
}

// Activity 中订阅
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
    // 处理事件
}

// Fragment 中发布
EventBus.getDefault().post(new MessageEvent("Hello!"));

优点

  • 简化组件间通信。
    缺点
  • 需引入第三方库,事件流难以跟踪。

4. 直接方法调用

实现方式

  • Activity 通过 FragmentManager 获取 Fragment 实例并调用其公共方法,反之亦然。
// Activity 调用 Fragment
MyFragment fragment = (MyFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
fragment.updateUI("New Data");

// Fragment 调用 Activity
((MainActivity) requireActivity()).showToast("Hello!");

优点

  • 简单直接。
    缺点
  • 高耦合性,破坏封装性。

5. Bundle 传递参数

实现方式

  • 通过 setArguments() 在 Fragment 初始化时传递数据,或在后续通过方法更新。
// 创建 Fragment 时传参
Bundle args = new Bundle();
args.putString("key", "value");
fragment.setArguments(args);

// Activity 中获取参数
String value = getArguments().getString("key");

优点

  • 适合初始数据传递。
    缺点
  • 无法实时通信。

最佳实践建议

  • 简单场景:使用接口回调或 ViewModel。
  • 跨组件通信:选择 EventBus 或 ViewModel。
  • 避免直接调用以防止耦合,优先使用观察者模式(如 LiveData)。

根据具体需求选择合适的方式,兼顾代码可维护性和灵活性。