You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:21:56