Android中Activity与Fragment怎么实现通信?
Android中Activity与Fragment通信的常见方式: 接口回调:Fragment定义接口,Activity实现,在onAttach()中绑定,适合Fragment向Activity单向传值; ViewModel:通过共享ViewModel实现双向通信,支持多Fragment数据同步,推荐使用LiveData观察数据变化; Activity中转:通过getActivity()获取宿主A
·
在Android开发中,Activity与Fragment之间的通信是常见需求。以下是几种主流的通信方式及其适用场景:
一、通过接口回调(推荐方式)
适用场景:Fragment向Activity传递数据
核心思路:
- Fragment定义接口,Activity实现该接口
- Fragment在
onAttach()中获取Activity实例并注册回调 - 事件发生时,Fragment调用接口方法通知Activity
示例代码:
// 1. Fragment中定义接口
public class MyFragment extends Fragment {
private OnDataPassListener listener;
public interface OnDataPassListener {
void onDataPass(String data);
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
try {
listener = (OnDataPassListener) context; // 获取Activity实例
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement OnDataPassListener");
}
}
// 在事件触发时调用接口方法
private void sendDataToActivity() {
listener.onDataPass("Hello from Fragment");
}
}
// 2. Activity实现接口
public class MainActivity extends AppCompatActivity
implements MyFragment.OnDataPassListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onDataPass(String data) {
// 处理从Fragment传来的数据
Log.d("MainActivity", "Received: " + data);
}
}
二、通过ViewModel共享数据(推荐方式)
适用场景:Activity与Fragment双向通信,或多Fragment间通信
核心思路:
- 使用Jetpack ViewModel存储共享数据
- Activity和Fragment通过同一ViewModel实例读写数据
- 数据变化时,观察者自动更新UI
示例代码:
// 1. 定义共享ViewModel
public class SharedViewModel extends ViewModel {
private final MutableLiveData<String> sharedData = new MutableLiveData<>();
public void setData(String data) {
sharedData.setValue(data);
}
public LiveData<String> getData() {
return sharedData;
}
}
// 2. Activity中使用ViewModel
public class MainActivity extends AppCompatActivity {
private SharedViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewModel = new ViewModelProvider(this).get(SharedViewModel.class);
// 观察数据变化
viewModel.getData().observe(this, data -> {
// 更新Activity UI
Log.d("MainActivity", "Received: " + data);
});
}
// 向Fragment发送数据
public void sendDataToFragment(String data) {
viewModel.setData(data);
}
}
// 3. Fragment中使用ViewModel
public class MyFragment extends Fragment {
private SharedViewModel viewModel;
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
viewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
// 观察数据变化
viewModel.getData().observe(getViewLifecycleOwner(), data -> {
// 更新Fragment UI
Log.d("MyFragment", "Received: " + data);
});
// 向Activity发送数据
viewModel.setData("Data from Fragment");
}
}
三、通过Activity作为中间层(简单场景)
适用场景:Fragment间通信
核心思路:
- Fragment通过
getActivity()获取Activity实例 - 调用Activity的公共方法
- Activity再将数据传递给目标Fragment
示例代码:
// 1. Activity提供公共方法
public class MainActivity extends AppCompatActivity {
public void passDataToFragment(String data) {
MyFragment fragment = (MyFragment) getSupportFragmentManager()
.findFragmentById(R.id.fragment_container);
if (fragment != null) {
fragment.updateUI(data);
}
}
}
// 2. 发送方Fragment调用Activity方法
public class SenderFragment extends Fragment {
public void sendData() {
MainActivity activity = (MainActivity) requireActivity();
activity.passDataToFragment("Hello from SenderFragment");
}
}
// 3. 接收方Fragment提供公共方法
public class MyFragment extends Fragment {
public void updateUI(String data) {
// 更新UI
}
}
四、通过全局事件总线(如EventBus)
适用场景:松耦合的事件传递,跨层级通信
核心思路:
- 添加依赖:
implementation 'org.greenrobot:eventbus:3.3.1' - 定义事件类
- 发送方发布事件,接收方订阅事件
示例代码:
// 1. 定义事件类
public class MessageEvent {
public final String message;
public MessageEvent(String message) {
this.message = message;
}
}
// 2. Fragment发送事件
public class MyFragment extends Fragment {
private void sendEvent() {
EventBus.getDefault().post(new MessageEvent("Hello from Fragment"));
}
}
// 3. Activity接收事件
public class MainActivity extends AppCompatActivity {
@Override
protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
// 订阅事件
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
Log.d("MainActivity", "Received: " + event.message);
}
}
五、通过Bundle传递数据(单向通信)
适用场景:Activity向Fragment传递数据
核心思路:
- Activity创建Fragment时,通过
setArguments()设置数据 - Fragment在
onCreate()中获取数据
示例代码:
// 1. Activity传递数据
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyFragment fragment = new MyFragment();
Bundle args = new Bundle();
args.putString("key", "Hello from Activity");
fragment.setArguments(args);
getSupportFragmentManager().beginTransaction()
.add(R.id.container, fragment)
.commit();
}
}
// 2. Fragment获取数据
public class MyFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
String data = getArguments().getString("key");
Log.d("MyFragment", "Received: " + data);
}
}
}
六、通过LocalBroadcastManager(跨进程通信)
适用场景:需要系统级广播的场景
核心思路:
- 使用
LocalBroadcastManager注册和发送广播 - 广播接收器在Activity/Fragment中处理消息
示例代码:
// 1. Fragment发送广播
public class MyFragment extends Fragment {
private void sendBroadcast() {
Intent intent = new Intent("custom-action");
intent.putExtra("data", "Hello from Fragment");
LocalBroadcastManager.getInstance(requireContext())
.sendBroadcast(intent);
}
}
// 2. Activity接收广播
public class MainActivity extends AppCompatActivity {
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String data = intent.getStringExtra("data");
Log.d("MainActivity", "Received: " + data);
}
};
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter("custom-action");
LocalBroadcastManager.getInstance(this)
.registerReceiver(receiver, filter);
}
@Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this)
.unregisterReceiver(receiver);
}
}
选择建议
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 接口回调 | 类型安全,显式依赖 | 代码量稍多 | Fragment → Activity |
| ViewModel | 生命周期感知,双向通信 | 需要Jetpack依赖 | 复杂通信场景 |
| Activity中间层 | 简单直接 | 耦合度高 | 简单的Fragment间通信 |
| EventBus | 松耦合,跨层级 | 隐式依赖,调试困难 | 跨组件事件分发 |
| Bundle | 简单轻量 | 只能单向传递静态数据 | Activity → Fragment |
| LocalBroadcastManager | 系统级广播,跨进程 | 性能开销大 | 需要全局事件的场景 |
推荐组合:
- 优先使用ViewModel + LiveData(官方推荐方案)
- 简单场景使用接口回调
- 跨模块通信考虑EventBus
注意事项
-
避免内存泄漏:
- 接口回调需在
onDetach()中置空引用 - EventBus/LocalBroadcast需在生命周期结束时取消注册
- 接口回调需在
-
生命周期管理:
- 使用
getViewLifecycleOwner()避免Fragment视图销毁后更新UI - ViewModel数据需在适当时候重置
- 使用
-
性能考虑:
- 避免频繁使用LocalBroadcastManager,优先使用轻量级方案
掌握这些通信方式,可使你的代码结构更清晰、可维护性更强。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)