深入分析 Android Activity (三)

文章目录

      • [深入分析 Android Activity (三)](#深入分析 Android Activity (三))
      • [1. Activity 的配置变化处理](#1. Activity 的配置变化处理)
        • [1.1 处理配置变化](#1.1 处理配置变化)
      • [2. Activity 的存储和恢复状态](#2. Activity 的存储和恢复状态)
        • [2.1 保存状态](#2.1 保存状态)
        • [2.2 恢复状态](#2.2 恢复状态)
      • [3. Activity 与 Fragment 的通信](#3. Activity 与 Fragment 的通信)
        • [3.1 通过接口进行通信](#3.1 通过接口进行通信)
        • [3.2 通过 ViewModel 进行通信](#3.2 通过 ViewModel 进行通信)
      • [4. Activity 的窗口管理和视图层次结构](#4. Activity 的窗口管理和视图层次结构)
        • [4.1 DecorView](#4.1 DecorView)
        • [4.2 Window 和 WindowManager](#4.2 Window 和 WindowManager)
      • [5. Activity 的任务和返回栈(Back Stack)](#5. Activity 的任务和返回栈(Back Stack))
        • [5.1 启动 Activity 的 Intent 标志](#5.1 启动 Activity 的 Intent 标志)
        • [5.2 处理返回栈中的数据](#5.2 处理返回栈中的数据)
      • 总结

深入分析 Android Activity (三)

1. Activity 的配置变化处理

当设备配置(如屏幕方向、语言、屏幕大小等)发生变化时,默认情况下,Android 会销毁并重新创建当前的 Activity。这种行为确保了新配置能够正确应用,但在某些情况下,重新创建 Activity 会带来性能问题或不必要的复杂性。

可以通过 android:configChanges 属性来指定当特定配置变化发生时,不销毁 Activity,而是调用 onConfigurationChanged 方法。

1.1 处理配置变化

AndroidManifest.xml 文件中声明需要处理的配置变化:

xml 复制代码
<activity android:name=".MyActivity"
    android:configChanges="orientation|screenSize|keyboardHidden">
</activity>

Activity 中覆盖 onConfigurationChanged 方法以处理配置变化:

java 复制代码
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Handle configuration changes
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        // Handle landscape orientation
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        // Handle portrait orientation
    }
}

2. Activity 的存储和恢复状态

为了在配置变化、进程被终止或其他情况发生时保存和恢复 Activity 的状态,可以使用 onSaveInstanceStateonRestoreInstanceState 方法。

2.1 保存状态

onSaveInstanceState 方法在 Activity 即将被销毁时调用,用于保存临时状态信息:

java 复制代码
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString("key", "value");
}
2.2 恢复状态

onRestoreInstanceState 方法在 Activity 被重新创建后调用,用于恢复之前保存的状态信息:

java 复制代码
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    String value = savedInstanceState.getString("key");
}

也可以在 onCreate 方法中恢复状态:

java 复制代码
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        String value = savedInstanceState.getString("key");
    }
}

3. Activity 与 Fragment 的通信

Fragment 是一个可重用的 UI 组件,能够在 Activity 中管理部分 UI 和逻辑。Fragment 可以独立于 Activity 管理自己的生命周期和状态。

3.1 通过接口进行通信

ActivityFragment 之间可以通过接口进行通信。在 Fragment 中定义一个接口,并在 Activity 中实现它:

java 复制代码
public class MyFragment extends Fragment {
    private OnFragmentInteractionListener mListener;

    public interface OnFragmentInteractionListener {
        void onFragmentInteraction(String data);
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnFragmentInteractionListener) {
            mListener = (OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener");
        }
    }

    // Call this method to send data to the activity
    public void sendDataToActivity(String data) {
        if (mListener != null) {
            mListener.onFragmentInteraction(data);
        }
    }
}

Activity 中实现接口方法:

java 复制代码
public class MyActivity extends AppCompatActivity implements MyFragment.OnFragmentInteractionListener {
    @Override
    public void onFragmentInteraction(String data) {
        // Handle interaction with the fragment
    }
}
3.2 通过 ViewModel 进行通信

使用 ViewModelLiveData 可以在 ActivityFragment 之间进行数据共享和通信,尤其是在 MVVM 架构中:

java 复制代码
public class SharedViewModel extends ViewModel {
    private final MutableLiveData<String> selected = new MutableLiveData<String>();

    public void select(String item) {
        selected.setValue(item);
    }

    public LiveData<String> getSelected() {
        return selected;
    }
}

Activity 中:

java 复制代码
public class MyActivity 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.getSelected().observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String item) {
                // Update the UI
            }
        });
    }
}

Fragment 中:

java 复制代码
public class MyFragment extends Fragment {
    private SharedViewModel viewModel;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_my, container, false);

        viewModel = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        viewModel.getSelected().observe(getViewLifecycleOwner(), new Observer<String>() {
            @Override
            public void onChanged(@Nullable String item) {
                // Update the UI
            }
        });

        return view;
    }
}

4. Activity 的窗口管理和视图层次结构

4.1 DecorView

DecorViewActivity 窗口中的最顶层视图容器,包含了状态栏、标题栏和内容区域。Window 类通过 setContentView 将视图层次结构添加到 DecorView 中。

java 复制代码
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}
4.2 Window 和 WindowManager

Window 是一个抽象类,表示一个顶级窗口。在大多数情况下,Activity 使用 PhoneWindow 类,它是 Window 的具体实现。WindowManager 是一个系统服务,负责管理窗口。

通过 WindowWindowManager 可以控制窗口的布局参数:

java 复制代码
Window window = getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.height = WindowManager.LayoutParams.MATCH_PARENT;
params.width = WindowManager.LayoutParams.MATCH_PARENT;
window.setAttributes(params);

5. Activity 的任务和返回栈(Back Stack)

Android 使用任务和返回栈来管理 Activity 的导航。每个任务由一个栈(返回栈)来管理 Activity

5.1 启动 Activity 的 Intent 标志

可以使用 Intent 标志来控制 Activity 的启动行为和返回栈。例如:

  • FLAG_ACTIVITY_NEW_TASK:在新的任务中启动 Activity
  • FLAG_ACTIVITY_CLEAR_TOP:如果目标 Activity 已经在栈中存在,则将其上面的所有 Activity 清除。
java 复制代码
Intent intent = new Intent(this, MyActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
5.2 处理返回栈中的数据

可以使用 onActivityResult 方法处理从另一个 Activity 返回的数据:

java 复制代码
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
        String result = data.getStringExtra("key");
        // Handle the result
    }
}

在启动 Activity 时可以传递请求代码:

java 复制代码
Intent intent = new Intent(this, AnotherActivity.class);
startActivityForResult(intent, REQUEST_CODE);

总结

Android 的 Activity 设计涉及生命周期管理、启动模式、视图层次结构、与 Fragment 的交互、进程和线程模型、任务和返回栈管理、以及配置变化处理。理解这些关键概念和内部实现,有助于开发者创建高效、稳定和响应迅速的应用程序。通过灵活应用这些知识,可以提升应用程序的用户体验和性能。

|----------------------------------|
| 欢迎点赞|关注|收藏|评论,您的肯定是我创作的动力 |

相关推荐
带电的小王2 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
梦想平凡2 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
元争栈道3 小时前
webview和H5来实现的android短视频(短剧)音视频播放依赖控件
android·音视频
阿甘知识库4 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
元争栈道4 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源
android·音视频
MuYe4 小时前
Android Hook - 动态加载so库
android
居居飒5 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
Henry_He8 小时前
桌面列表小部件不能点击的问题分析
android
工程师老罗8 小时前
Android笔试面试题AI答之Android基础(1)
android
qq_3975623110 小时前
android studio更改应用图片,和应用名字。
android·ide·android studio