Android 的 Activity 与 Fragment 交互模块深度剖析
本人掘金号,欢迎点击关注:掘金号地址
本人公众号,欢迎点击关注:公众号地址
一、引言
在 Android 开发中,Activity 和 Fragment 是两个至关重要的组件。Activity 作为 Android 应用的可视化界面容器,为用户提供了与应用交互的窗口;而 Fragment 则是 Activity 中的模块化组件,能够实现界面的灵活组合和复用。Activity 与 Fragment 之间的交互机制是 Android 开发中不可或缺的一部分,它使得开发者可以构建出更加复杂、灵活且富有交互性的应用界面。
本博客将从源码级别深入分析 Android 的 Activity 与 Fragment 交互模块,详细探讨它们之间各种交互方式的实现原理,帮助开发者更好地理解和运用这一重要机制。
二、Activity 与 Fragment 基础概念回顾
2.1 Activity 概述
Activity 是 Android 应用中最基本的组件之一,它代表了一个具有用户界面的单屏。每个 Activity 都有自己的生命周期,从创建、启动、暂停、恢复到销毁,开发者可以通过重写相应的生命周期方法来实现特定的逻辑。
以下是一个简单的 Activity 示例:
java
java
import android.app.Activity;
import android.os.Bundle;
// 自定义 Activity 类,继承自 Activity
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// 调用父类的 onCreate 方法
super.onCreate(savedInstanceState);
// 设置 Activity 的布局文件
setContentView(R.layout.activity_main);
}
}
在上述代码中,onCreate
方法是 Activity 生命周期中的一个重要方法,它在 Activity 首次创建时被调用。在该方法中,我们调用了 setContentView
方法来设置 Activity 的布局文件。
2.2 Fragment 概述
Fragment 是 Android 3.0(API 级别 11)引入的一个概念,它可以被看作是 Activity 中的一个子模块,有自己的生命周期和布局。Fragment 可以动态地添加、替换和移除,使得界面的管理更加灵活。
以下是一个简单的 Fragment 示例:
java
java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
// 自定义 Fragment 类,继承自 Fragment
public class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 加载 Fragment 的布局文件
return inflater.inflate(R.layout.fragment_my, container, false);
}
}
在上述代码中,onCreateView
方法是 Fragment 生命周期中的一个重要方法,它在 Fragment 创建视图时被调用。在该方法中,我们使用 LayoutInflater
来加载 Fragment 的布局文件。
2.3 Activity 与 Fragment 的关系
Fragment 必须依赖于 Activity 而存在,它的生命周期受到 Activity 生命周期的影响。一个 Activity 可以包含多个 Fragment,通过 FragmentManager
来管理这些 Fragment。Fragment 可以与 Activity 进行交互,实现数据的传递和界面的更新。
三、Activity 向 Fragment 传递数据
3.1 使用 Bundle 传递数据
在 Activity 中创建 Fragment 时,可以通过 Bundle
对象来传递数据。Bundle
是一个键值对的集合,类似于 Map
,可以存储各种基本数据类型和可序列化的对象。
以下是一个 Activity 向 Fragment 传递数据的示例:
java
java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
// 自定义 Fragment 类,继承自 Fragment
public class DataReceiverFragment extends Fragment {
private static final String ARG_DATA = "data";
private String mData;
// 静态工厂方法,用于创建 Fragment 实例并传递数据
public static DataReceiverFragment newInstance(String data) {
DataReceiverFragment fragment = new DataReceiverFragment();
Bundle args = new Bundle();
// 将数据存入 Bundle 中
args.putString(ARG_DATA, data);
// 将 Bundle 设置为 Fragment 的参数
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
// 从 Bundle 中获取数据
mData = getArguments().getString(ARG_DATA);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 加载 Fragment 的布局文件
View view = inflater.inflate(R.layout.fragment_data_receiver, container, false);
TextView textView = view.findViewById(R.id.textView);
// 将获取到的数据显示在 TextView 上
textView.setText(mData);
return view;
}
}
在 Activity 中使用该 Fragment 并传递数据:
java
java
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentTransaction;
// 自定义 Activity 类,继承自 AppCompatActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建要传递的数据
String data = "Hello from Activity!";
// 创建 Fragment 实例并传递数据
DataReceiverFragment fragment = DataReceiverFragment.newInstance(data);
// 获取 FragmentManager
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// 将 Fragment 添加到布局中
transaction.add(R.id.fragment_container, fragment);
// 提交事务
transaction.commit();
}
}
3.1.1 源码分析
在 DataReceiverFragment
中,newInstance
方法是一个静态工厂方法,用于创建 DataReceiverFragment
的实例并传递数据。在该方法中,我们创建了一个 Bundle
对象,并将数据存入其中,然后调用 setArguments
方法将 Bundle
设置为 Fragment 的参数。
在 onCreate
方法中,我们通过 getArguments
方法获取之前设置的 Bundle
,并从中取出数据。
在 MainActivity
中,我们创建了要传递的数据,并调用 DataReceiverFragment
的 newInstance
方法创建 Fragment 实例。然后,我们获取 FragmentManager
并开始一个事务,将 Fragment 添加到布局中,最后提交事务。
3.2 通过接口回调传递数据
Activity 可以通过接口回调的方式向 Fragment 传递数据。具体步骤如下:
-
在 Fragment 中定义一个接口。
-
在 Activity 中实现该接口。
-
在 Fragment 中设置接口的实现对象。
-
在 Activity 中调用接口的方法传递数据。
以下是一个示例:
java
java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
// 自定义 Fragment 类,继承自 Fragment
public class CallbackReceiverFragment extends Fragment {
private OnDataReceivedListener mListener;
private TextView mTextView;
// 定义接口
public interface OnDataReceivedListener {
void onDataReceived(String data);
}
// 设置接口的实现对象
public void setOnDataReceivedListener(OnDataReceivedListener listener) {
mListener = listener;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 加载 Fragment 的布局文件
View view = inflater.inflate(R.layout.fragment_callback_receiver, container, false);
mTextView = view.findViewById(R.id.textView);
return view;
}
// 处理接收到的数据
public void handleData(String data) {
if (mTextView != null) {
mTextView.setText(data);
}
}
}
在 Activity 中实现该接口并传递数据:
java
java
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
// 自定义 Activity 类,继承自 AppCompatActivity
public class MainActivity extends AppCompatActivity implements CallbackReceiverFragment.OnDataReceivedListener {
private CallbackReceiverFragment mFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建 Fragment 实例
mFragment = new CallbackReceiverFragment();
// 设置接口的实现对象
mFragment.setOnDataReceivedListener(this);
// 获取 FragmentManager
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, mFragment)
.commit();
// 传递数据
sendDataToFragment();
}
private void sendDataToFragment() {
String data = "Hello from Activity via callback!";
// 调用接口的方法传递数据
onDataReceived(data);
}
@Override
public void onDataReceived(String data) {
// 调用 Fragment 的方法处理数据
mFragment.handleData(data);
}
}
3.2.1 源码分析
在 CallbackReceiverFragment
中,我们定义了一个 OnDataReceivedListener
接口,该接口包含一个 onDataReceived
方法,用于接收数据。
setOnDataReceivedListener
方法用于设置接口的实现对象。
handleData
方法用于处理接收到的数据,将数据显示在 TextView
上。
在 MainActivity
中,我们实现了 OnDataReceivedListener
接口,并在 onCreate
方法中创建了 CallbackReceiverFragment
实例,设置了接口的实现对象。
sendDataToFragment
方法用于创建要传递的数据,并调用 onDataReceived
方法传递数据。
onDataReceived
方法中,我们调用 CallbackReceiverFragment
的 handleData
方法处理数据。
四、Fragment 向 Activity 传递数据
4.1 使用接口回调传递数据
Fragment 向 Activity 传递数据最常用的方式也是接口回调。具体步骤如下:
-
在 Fragment 中定义一个接口。
-
在 Activity 中实现该接口。
-
在 Fragment 中设置接口的实现对象。
-
在 Fragment 中调用接口的方法传递数据。
以下是一个示例:
java
java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.fragment.app.Fragment;
// 自定义 Fragment 类,继承自 Fragment
public class DataSenderFragment extends Fragment {
private OnDataSendListener mListener;
private Button mSendButton;
// 定义接口
public interface OnDataSendListener {
void onDataSent(String data);
}
// 设置接口的实现对象
public void setOnDataSendListener(OnDataSendListener listener) {
mListener = listener;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 加载 Fragment 的布局文件
View view = inflater.inflate(R.layout.fragment_data_sender, container, false);
mSendButton = view.findViewById(R.id.sendButton);
// 为按钮设置点击事件监听器
mSendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 传递数据
sendDataToActivity();
}
});
return view;
}
private void sendDataToActivity() {
String data = "Hello from Fragment!";
if (mListener != null) {
// 调用接口的方法传递数据
mListener.onDataSent(data);
}
}
}
在 Activity 中实现该接口并处理数据:
java
java
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
// 自定义 Activity 类,继承自 AppCompatActivity
public class MainActivity extends AppCompatActivity implements DataSenderFragment.OnDataSendListener {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.textView);
// 创建 Fragment 实例
DataSenderFragment fragment = new DataSenderFragment();
// 设置接口的实现对象
fragment.setOnDataSendListener(this);
// 获取 FragmentManager
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
@Override
public void onDataSent(String data) {
// 处理接收到的数据
mTextView.setText(data);
}
}
4.1.1 源码分析
在 DataSenderFragment
中,我们定义了一个 OnDataSendListener
接口,该接口包含一个 onDataSent
方法,用于传递数据。
setOnDataSendListener
方法用于设置接口的实现对象。
sendDataToActivity
方法用于创建要传递的数据,并调用接口的 onDataSent
方法传递数据。
在 MainActivity
中,我们实现了 OnDataSendListener
接口,并在 onCreate
方法中创建了 DataSenderFragment
实例,设置了接口的实现对象。
onDataSent
方法用于处理接收到的数据,将数据显示在 TextView
上。
4.2 通过 Activity 的公共方法传递数据
Fragment 还可以通过调用 Activity 的公共方法来传递数据。具体步骤如下:
-
在 Activity 中定义公共方法。
-
在 Fragment 中获取 Activity 的实例。
-
调用 Activity 的公共方法传递数据。
以下是一个示例:
java
java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.fragment.app.Fragment;
// 自定义 Fragment 类,继承自 Fragment
public class MethodCallSenderFragment extends Fragment {
private Button mSendButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 加载 Fragment 的布局文件
View view = inflater.inflate(R.layout.fragment_method_call_sender, container, false);
mSendButton = view.findViewById(R.id.sendButton);
// 为按钮设置点击事件监听器
mSendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 传递数据
sendDataToActivity();
}
});
return view;
}
private void sendDataToActivity() {
String data = "Hello from Fragment via method call!";
// 获取 Activity 的实例
MainActivity activity = (MainActivity) getActivity();
if (activity != null) {
// 调用 Activity 的公共方法传递数据
activity.receiveData(data);
}
}
}
在 Activity 中定义公共方法并处理数据:
java
java
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
// 自定义 Activity 类,继承自 AppCompatActivity
public class MainActivity extends AppCompatActivity {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.textView);
// 创建 Fragment 实例
MethodCallSenderFragment fragment = new MethodCallSenderFragment();
// 获取 FragmentManager
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
// 公共方法,用于接收数据
public void receiveData(String data) {
// 处理接收到的数据
mTextView.setText(data);
}
}
4.2.1 源码分析
在 MethodCallSenderFragment
中,sendDataToActivity
方法用于创建要传递的数据,并通过 getActivity
方法获取 Activity 的实例。
然后,我们将获取到的 Activity 实例强制转换为 MainActivity
类型,并调用其 receiveData
方法传递数据。
在 MainActivity
中,我们定义了一个公共方法 receiveData
,用于接收数据并将其显示在 TextView
上。
五、Activity 与 Fragment 之间的事件交互
5.1 Activity 监听 Fragment 的事件
Activity 可以监听 Fragment 中的事件,例如按钮点击事件。通过接口回调的方式,Fragment 可以将事件传递给 Activity。
以下是一个示例:
java
java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.fragment.app.Fragment;
// 自定义 Fragment 类,继承自 Fragment
public class EventSenderFragment extends Fragment {
private OnButtonClickListener mListener;
private Button mButton;
// 定义接口
public interface OnButtonClickListener {
void onButtonClicked();
}
// 设置接口的实现对象
public void setOnButtonClickListener(OnButtonClickListener listener) {
mListener = listener;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 加载 Fragment 的布局文件
View view = inflater.inflate(R.layout.fragment_event_sender, container, false);
mButton = view.findViewById(R.id.button);
// 为按钮设置点击事件监听器
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 触发事件
if (mListener != null) {
mListener.onButtonClicked();
}
}
});
return view;
}
}
在 Activity 中实现该接口并处理事件:
java
java
import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
// 自定义 Activity 类,继承自 AppCompatActivity
public class MainActivity extends AppCompatActivity implements EventSenderFragment.OnButtonClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建 Fragment 实例
EventSenderFragment fragment = new EventSenderFragment();
// 设置接口的实现对象
fragment.setOnButtonClickListener(this);
// 获取 FragmentManager
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
@Override
public void onButtonClicked() {
// 处理事件
Toast.makeText(this, "Button in Fragment is clicked!", Toast.LENGTH_SHORT).show();
}
}
5.1.1 源码分析
在 EventSenderFragment
中,我们定义了一个 OnButtonClickListener
接口,该接口包含一个 onButtonClicked
方法,用于处理按钮点击事件。
setOnButtonClickListener
方法用于设置接口的实现对象。
在按钮的点击事件监听器中,我们调用接口的 onButtonClicked
方法触发事件。
在 MainActivity
中,我们实现了 OnButtonClickListener
接口,并在 onCreate
方法中创建了 EventSenderFragment
实例,设置了接口的实现对象。
onButtonClicked
方法用于处理按钮点击事件,显示一个 Toast
消息。
5.2 Fragment 监听 Activity 的事件
Fragment 也可以监听 Activity 中的事件,例如 Activity 的菜单点击事件。通过在 Fragment 中重写 onActivityCreated
方法,获取 Activity 的菜单,并为菜单项设置点击事件监听器。
以下是一个示例:
java
java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
// 自定义 Fragment 类,继承自 Fragment
public class EventReceiverFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 加载 Fragment 的布局文件
return inflater.inflate(R.layout.fragment_event_receiver, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// 获取 Activity 的菜单
Menu menu = getActivity().getMenuInflater().inflate(R.menu.main_menu, null);
// 为菜单项设置点击事件监听器
MenuItem item = menu.findItem(R.id.menu_item);
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
// 处理事件
Toast.makeText(getActivity(), "Menu item in Activity is clicked!", Toast.LENGTH_SHORT).show();
return true;
}
});
}
}
在 Activity 中加载菜单:
java
java
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentTransaction;
// 自定义 Activity 类,继承自 AppCompatActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 创建 Fragment 实例
EventReceiverFragment fragment = new EventReceiverFragment();
// 获取 FragmentManager
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// 将 Fragment 添加到布局中
transaction.add(R.id.fragment_container, fragment);
// 提交事务
transaction.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// 加载菜单资源
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
}
5.2.1 源码分析
在 EventReceiverFragment
中,onActivityCreated
方法在 Activity 创建完成后被调用。在该方法中,我们获取 Activity 的菜单,并为菜单项设置点击事件监听器。
在点击事件监听器中,我们处理菜单项的点击事件,显示一个 Toast
消息。
在 MainActivity
中,onCreateOptionsMenu
方法用于加载菜单资源。
六、使用 ViewModel 进行 Activity 与 Fragment 之间的数据共享
6.1 ViewModel 概述
ViewModel 是 Android Architecture Components 中的一个组件,它用于存储和管理与 UI 相关的数据,并且在配置更改(如屏幕旋转)时保持数据的一致性。ViewModel 可以在 Activity 和 Fragment 之间共享数据,避免了数据在 Activity 和 Fragment 之间的重复传递。
6.2 使用 ViewModel 共享数据的示例
以下是一个使用 ViewModel 进行 Activity 与 Fragment 之间数据共享的示例:
java
java
import androidx.lifecycle.ViewModel;
// 自定义 ViewModel 类,继承自 ViewModel
public class SharedViewModel extends ViewModel {
private String mData;
// 获取数据
public String getData() {
return mData;
}
// 设置数据
public void setData(String data) {
mData = data;
}
}
在 Activity 中使用 ViewModel 并设置数据:
java
java
import android.os.Bundle;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
// 自定义 Activity 类,继承自 AppCompatActivity
public class MainActivity extends AppCompatActivity {
private SharedViewModel mViewModel;
private Button mSetDataButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取 ViewModel 实例
mViewModel = new ViewModelProvider(this).get(SharedViewModel.class);
mSetDataButton = findViewById(R.id.setDataButton);
// 为按钮设置点击事件监听器
mSetDataButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 设置数据
mViewModel.setData("Hello from Activity via ViewModel!");
}
});
}
}
在 Fragment 中使用 ViewModel 并获取数据:
java
java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
// 自定义 Fragment 类,继承自 Fragment
public class DataReceiverViewModelFragment extends Fragment {
private SharedViewModel mViewModel;
private TextView mTextView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 加载 Fragment 的布局文件
View view = inflater.inflate(R.layout.fragment_data_receiver_viewmodel, container, false);
mTextView = view.findViewById(R.id.textView);
// 获取 ViewModel 实例
mViewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
// 观察数据的变化
mViewModel.getData().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(String data) {
// 处理数据的变化
mTextView.setText(data);
}
});
return view;
}
}
6.2.1 源码分析
在 SharedViewModel
中,我们定义了一个 mData
变量,并提供了 getData
和 setData
方法来获取和设置数据。
在 MainActivity
中,我们通过 ViewModelProvider
获取 SharedViewModel
的实例,并在按钮的点击事件监听器中调用 setData
方法设置数据。
在 DataReceiverViewModelFragment
中,我们同样通过 ViewModelProvider
获取 SharedViewModel
的实例,并使用 observe
方法观察数据的变化。当数据发生变化时,onChanged
方法会被调用,我们在该方法中更新 TextView
的文本。
七、Activity 与 Fragment 交互的生命周期影响
7.1 Activity 生命周期对 Fragment 的影响
Activity 的生命周期会直接影响 Fragment 的生命周期。当 Activity 进入不同的生命周期状态时,Fragment 也会相应地进入不同的生命周期状态。
例如,当 Activity 的 onCreate
方法被调用时,Fragment 的 onAttach
、onCreate
和 onCreateView
方法会依次被调用。
以下是 Activity 和 Fragment 生命周期方法的调用顺序示例:
java
java
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
// 自定义 Activity 类,继承自 FragmentActivity
public class LifecycleActivity extends FragmentActivity {
private static final String TAG = "LifecycleActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lifecycle);
Log.d(TAG, "Activity onCreate");
// 创建 Fragment 实例
LifecycleFragment fragment = new LifecycleFragment();
// 获取 FragmentManager
FragmentManager manager = getSupportFragmentManager();
// 开始事务
FragmentTransaction transaction = manager.beginTransaction();
// 添加 Fragment
transaction.add(R.id.fragment_container, fragment);
// 提交事务
transaction.commit();
}
@Override
protected void onStart() {
super.onStart();
Log.d(TAG, "Activity onStart");
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "Activity onResume");
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "Activity onPause");
}
@Override
protected void onStop() {
super.onStop();
Log.d(TAG, "Activity onStop");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "Activity onDestroy");
}
}
// 自定义 Fragment 类,继承自 Fragment
public class LifecycleFragment extends Fragment {
private static final String TAG = "LifecycleFragment";
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.d(TAG, "Fragment onAttach");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "Fragment onCreate");
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "Fragment onCreateView");
return inflater.inflate(R.layout.fragment_lifecycle, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.d(TAG, "Fragment onActivityCreated");
}
@Override
public void onStart() {
super.onStart();
Log.d(TAG, "Fragment onStart");
}
@Override
public void onResume() {
super.onResume();
Log.d(TAG, "Fragment onResume");
}
@Override
public void onPause() {
super.onPause();
Log.d(TAG, "Fragment onPause");
}
@Override
public void onStop() {
super.onStop();
Log.d(TAG, "Fragment onStop");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.d(TAG, "Fragment onDestroyView");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "Fragment onDestroy");
}
@Override
public void onDetach() {
super.onDetach();
Log.d(TAG, "Fragment onDetach");
}
}
7.1.1 源码分析
在 LifecycleActivity
中,我们重写了 Activity 的生命周期方法,并在每个方法中打印日志。
在 onCreate
方法中,我们创建了 LifecycleFragment
实例,并将其添加到布局中。
在 LifecycleFragment
中,我们重写了 Fragment 的生命周期方法,并在每个方法中打印日志。
通过运行该示例,我们可以观察到 Activity 和 Fragment 生命周期方法的调用顺序。
7.2 Fragment 生命周期对 Activity 交互的影响
Fragment 的生命周期也会影响 Activity 与 Fragment 之间的交互。例如,在 Fragment 的 onDestroyView
方法中,视图已经被销毁,如果此时 Activity 尝试访问 Fragment 的视图,会导致空指针异常。
因此,在进行 Activity 与 Fragment 交互时,需要注意 Fragment 的生命周期状态,确保在合适的时机进行交互。
八、总结与展望
8.1 总结
通过对 Android 的 Activity 与 Fragment 交互模块的深入分析,我们了解了多种 Activity 与 Fragment 之间的交互方式,包括使用 Bundle
传递数据、接口回调、公共方法调用、ViewModel 数据共享等。
每种交互方式都有其适用场景和优缺点。使用 Bundle
传递数据简单直接,适用于在创建 Fragment 时传递静态数据;接口回调方式灵活,适用于传递事件和动态数据;公共方法调用方式直观,适用于 Fragment 直接调用 Activity 的方法;ViewModel 数据共享方式适用于在 Activity 和 Fragment 之间共享动态数据,并且可以在配置更改时保持数据的一致性。
同时,我们还分析了 Activity 和 Fragment 的生命周期对交互的影响,了解到在进行交互时需要注意生命周期状态,避免出现空指针异常等问题。
8.2 展望
随着 Android 开发技术的不断发展,Activity 与 Fragment 交互模块可能会有更多的优化和改进。例如,可能会出现更简洁、更高效的交互方式,或者对现有交互方式进行进一步的封装和简化。
在性能方面,可能会对交互过程中的数据传递和事件处理进行优化,减少不必要的内存开销和性能损耗。
在兼容性方面,会更好地支持不同版本的 Android 系统,确保开发者在不同的设备上都能稳定地使用 Activity 与 Fragment 交互功能。
此外,随着 Android 应用的复杂度不断增加,Activity 与 Fragment 交互模块可能会与其他组件和技术进行更深入的融合,为开发者提供更强大的开发工具和功能。
总之,Activity 与 Fragment 交互模块是 Android 开发中非常重要的一部分,深入理解和掌握其原理和使用方法,对于开发高质量的 Android 应用具有重要意义。开发者需要不断关注技术的发展,灵活运用各种交互方式,以满足不同的开发需求。