Android双Activity交互实现咨询:Communicator与FragmentManager两种方案
没问题,我来帮你梳理这两种实现方案~先提一句:你提到的Upper和Lower应该是Fragment(毕竟后面用到了FragmentManager相关操作),我就按这个前提来写代码示例啦!
方案一:通过Communicator接口实现通信
这种方式是Android官方推荐的Fragment通信模式,借助宿主Activity作为中间桥梁,实现两个Fragment的解耦通信。
1. 定义Communicator接口
先创建一个接口作为通信契约,规定数值变化时的回调方法:
// Communicator.java public interface Communicator { void onValueChanged(int newValue); }
2. 宿主MainActivity实现接口
MainActivity需要实现这个接口,负责接收Upper的数值变化通知,并转发给Lower:
// MainActivity.java public class MainActivity extends AppCompatActivity implements Communicator { private int currentValue = 0; private Lower lowerFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化并加载两个Fragment到布局容器 FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.upper_container, new Upper()); lowerFragment = new Lower(); ft.add(R.id.lower_container, lowerFragment); ft.commit(); } @Override public void onValueChanged(int newValue) { currentValue = newValue; // 确保Lower Fragment已附加,再通知更新UI if (lowerFragment != null && lowerFragment.isAdded()) { lowerFragment.updateValue(currentValue); } } }
3. Upper Fragment调用接口传递数值
Upper在绑定到Activity时获取Communicator实例,点击按钮时触发接口方法传递数值:
// Upper.java public class Upper extends Fragment { private Communicator communicator; private int currentValue = 0; @Override public void onAttach(@NonNull Context context) { super.onAttach(context); // 强制要求宿主Activity实现Communicator接口 if (context instanceof Communicator) { communicator = (Communicator) context; } else { throw new RuntimeException(context.toString() + " 必须实现Communicator接口"); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_upper, container, false); Button btnAdd = view.findViewById(R.id.btn_add); Button btnSubtract = view.findViewById(R.id.btn_subtract); btnAdd.setOnClickListener(v -> { currentValue++; communicator.onValueChanged(currentValue); }); btnSubtract.setOnClickListener(v -> { currentValue--; communicator.onValueChanged(currentValue); }); return view; } @Override public void onDetach() { super.onDetach(); communicator = null; // 避免内存泄漏 } }
4. Lower Fragment提供UI更新方法
Lower暴露一个更新数值的方法,供MainActivity调用:
// Lower.java public class Lower extends Fragment { private TextView tvValue; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_lower, container, false); tvValue = view.findViewById(R.id.tv_value); tvValue.setText(String.valueOf(0)); // 初始显示0 return view; } // 供外部调用的UI更新方法 public void updateValue(int value) { if (tvValue != null) { tvValue.setText(String.valueOf(value)); } } }
方案二:不使用接口,通过FragmentManager直接获取实例通信
这种方式更简洁,直接让Upper通过FragmentManager找到Lower实例并调用其方法,但会增加两个Fragment的耦合性,适合简单场景。
1. MainActivity初始化Fragment时设置Tag
给Lower Fragment设置唯一Tag,方便后续查找:
// MainActivity.java public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentManager fm = getSupportFragmentManager(); FragmentTransaction ft = fm.beginTransaction(); ft.add(R.id.upper_container, new Upper()); // 设置Tag,后续通过Tag查找Lower ft.add(R.id.lower_container, new Lower(), "LOWER_FRAGMENT"); ft.commit(); } }
2. Upper直接查找Lower并更新数值
Upper在点击按钮时,通过FragmentManager获取Lower实例,直接调用其更新方法:
// Upper.java public class Upper extends Fragment { private int currentValue = 0; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_upper, container, false); Button btnAdd = view.findViewById(R.id.btn_add); Button btnSubtract = view.findViewById(R.id.btn_subtract); btnAdd.setOnClickListener(v -> { currentValue++; updateLowerValue(currentValue); }); btnSubtract.setOnClickListener(v -> { currentValue--; updateLowerValue(currentValue); }); return view; } private void updateLowerValue(int value) { // 通过Tag获取Lower实例 Lower lowerFragment = (Lower) getActivity().getSupportFragmentManager().findFragmentByTag("LOWER_FRAGMENT"); // 确保Fragment已附加到Activity再操作 if (lowerFragment != null && lowerFragment.isAdded()) { lowerFragment.updateValue(value); } } }
3. Lower Fragment代码不变
和方案一的Lower代码完全一致,依旧保留updateValue方法即可。
两种方案对比
- 方案一:遵循解耦原则,Fragment之间不直接依赖,后续扩展或修改更灵活,适合复杂场景。
- 方案二:代码更简洁,但Fragment耦合性高,如果后续Lower被替换或移除,容易出现空指针问题,适合简单的小型项目。
内容的提问来源于stack exchange,提问作者user3215990
相关产品推荐
相关产品推荐

