在Android开发中,Activity与Fragment之间的通信是常见需求。以下是几种主流的通信方式及其适用场景:

一、通过接口回调(推荐方式)

适用场景:Fragment向Activity传递数据
核心思路

  1. Fragment定义接口,Activity实现该接口
  2. Fragment在onAttach()中获取Activity实例并注册回调
  3. 事件发生时,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间通信
核心思路

  1. 使用Jetpack ViewModel存储共享数据
  2. Activity和Fragment通过同一ViewModel实例读写数据
  3. 数据变化时,观察者自动更新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间通信
核心思路

  1. Fragment通过getActivity()获取Activity实例
  2. 调用Activity的公共方法
  3. 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)

适用场景:松耦合的事件传递,跨层级通信
核心思路

  1. 添加依赖:implementation 'org.greenrobot:eventbus:3.3.1'
  2. 定义事件类
  3. 发送方发布事件,接收方订阅事件

示例代码

// 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传递数据
核心思路

  1. Activity创建Fragment时,通过setArguments()设置数据
  2. 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(跨进程通信)

适用场景:需要系统级广播的场景
核心思路

  1. 使用LocalBroadcastManager注册和发送广播
  2. 广播接收器在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

注意事项

  1. 避免内存泄漏

    • 接口回调需在onDetach()中置空引用
    • EventBus/LocalBroadcast需在生命周期结束时取消注册
  2. 生命周期管理

    • 使用getViewLifecycleOwner()避免Fragment视图销毁后更新UI
    • ViewModel数据需在适当时候重置
  3. 性能考虑

    • 避免频繁使用LocalBroadcastManager,优先使用轻量级方案

掌握这些通信方式,可使你的代码结构更清晰、可维护性更强。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐