首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【Android】屏幕翻转导致数据丢失解决方案——数据持久化

【Android】屏幕翻转导致数据丢失解决方案——数据持久化

作者头像
三三是该溜子
发布2025-08-23 08:24:15
发布2025-08-23 08:24:15
14100
代码可运行
举报
文章被收录于专栏:该溜子的专栏该溜子的专栏
运行总次数:0
代码可运行

一:翻转屏幕时生命周期变化

经典场景:翻转屏幕

代码语言:javascript
代码运行次数:0
运行
复制
public class ConfigChangesActivity extends AppCompatActivity {
    private static final String TAG = "ConfigChangesActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, TAG + "onCreate: 已经创建");
        setContentView(R.layout.activity_config_changes);

    }

    /**
     * 已开始:Activity会进入到前台
     */
    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG, TAG + " onStart: 已开始");
    }

    /**
     * 已恢复:可以和用户进行交互
     */
    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, TAG + " onResume: 已恢复");
    }

    /**
     * 已暂停:不是被销毁,只是暂时离开Activity
     */
    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, TAG + " onPause: 已暂停");
    }

    /**
     * 已停止:Activity页面不会被附加到窗口管理当中,但是Activity本身的一些成员变量、状态还会存在
     */
    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, TAG + " onStop: 已停止");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i(TAG, TAG + " onRestart: 准备重新触发onStart");
    }

    /**
     * Activity被销毁之前,会调用这个方法
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, TAG + " onDestroy: 准备销毁当前页面!");
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
            Log.i(TAG, "onConfigurationChanged: ORIENTATION_LANDSCAPE");
        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {

        }
    }
}

布局

二:数据持久化

提问:页面翻转导致Activity被销毁,那么对应的数据也会丢失,怎么解决?

1:清单中设置屏幕方向

(1)landscape

当前Activity一启动就是横屏的状态,landscape 横向格式

android:screenOrientation="landscape"

  • portrait:只允许竖屏模式 portrait [ˈpɔːtreɪt] 竖向的
  • landscape:只允许横屏模式。
  • sensor:根据设备的物理方向传感器来自动切换屏幕方向。
  • user:根据用户的屏幕方向设置来确定屏幕方向。
  • nosensor:忽略方向传感器并使用当前的显示方向。

2:configChanges

我就是想让当前的方向随屏幕方向是横屏或者竖屏,并且可以在相应横屏或者竖屏跳转时进行一些代码逻辑的处理

代码语言:javascript
代码运行次数:0
运行
复制
<activity
            android:name=".activity.ConfigChangesActivity"
            android:configChanges="orientation|screenSize"
            android:exported="true" />

3:onConfigurationChanged

android:configChanges="orientation|screenSize" 用于指定当设备发生这些配置变化时,系统不销毁并重建当前 Activity,而是由开发者自己处理配置变化

在ConfigChangesActivity类中重写onConfigurationChanged方法

代码语言:javascript
代码运行次数:0
运行
复制
 @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
            Log.i(TAG, "onConfigurationChanged: ORIENTATION_LANDSCAPE");
        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {

        }
    }

很多商业场景中会使用configChanges,但不是必用的这玩意,这里只是讲的详细一点

三:Activity的数据持久化

显然上面这种方式对于数据丢失是治标不治本的

1:场景引入

代码语言:javascript
代码运行次数:0
运行
复制
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.SaveDataActivity">

    <EditText
        android:id="@+id/et_nick_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:hint="请输入昵称"
        app:layout_constraintVertical_bias="0.3"/>

    <EditText
        android:id="@+id/et_age"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入年龄"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/et_nick_name" />

    <Button
        android:id="@+id/btn_commit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="提交"
        app:layout_constraintEnd_toEndOf="@id/et_age"
        app:layout_constraintTop_toBottomOf="@id/et_age" />

</androidx.constraintlayout.widget.ConstraintLayout>

2:问题分析

我们试想一个场景,运行Activity类,在输入框中输入昵称和密码,返回主屏幕,时间一长,系统可能因为内存不足就把Activity销毁了,那成员变量中保存的数据就没了,在我们的视角当中就是返回页面的时候,之前输入框中输入的数据没了

那怎么才能做到数据的持久存储呢,或者数据恢复呢?

代码语言:javascript
代码运行次数:0
运行
复制
public class SaveDataActivity extends AppCompatActivity {
    private static final String TAG = "SaveDataActivity";

    private String nickName;
    private String age;
    private EditText edNickName;
    private EditText edAge;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_save_data);

        if(savedInstanceState != null){
            nickName = savedInstanceState.getString("key_nickName");
            age = savedInstanceState.getString("key_age");
            Log.i(TAG, "onCreate: 我在OnCreate方法中利用savedInstanceState恢复数据了");
        }

        edNickName = findViewById(R.id.et_nick_name);
        edAge = findViewById(R.id.et_age);


        findViewById(R.id.btn_commit).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                nickName = edNickName.getText().toString();
                age = edAge.getText().toString();
            }
        });
        Log.i(TAG, "onCreate: ");

    }


}

3:onSaveInstanceState

  • 保存数据
    • activity进入后台有可能会被销毁,系统会在销毁前调用该方法
    • Activity配置发生变化,会调用
    • 用户按下home、接电话,会调用
代码语言:javascript
代码运行次数:0
运行
复制
    /**
     * 保存数据
     * @param outState Bundle in which to place your saved state.
     *
     */
    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString("key_nickName",nickName);
        outState.putString("key_age",age);
        Log.i(TAG, "onSaveInstanceState: 保存日志");
    }
(1)效果

数据确实被杀掉的情况下,onSaveInstanceState才会被调用

4:onRestoreInstanceState

有保存就有恢复方法,两者是相辅相成的

代码语言:javascript
代码运行次数:0
运行
复制
    @Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        nickName = savedInstanceState.getString("key_nickName");
        age = savedInstanceState.getString("key_age");

        //恢复ui的显示
        edNickName.setText(nickName);
        edAge.setText(age);

        Log.i(TAG, "onRestoreInstanceState: ");
    }

四:saveInstanceState恢复数据

代码语言:javascript
代码运行次数:0
运行
复制
		if(savedInstanceState != null){
            nickName = savedInstanceState.getString("key_nickName");
            age = savedInstanceState.getString("key_age");
            Log.i(TAG, "onCreate: 我在OnCreate方法中利用savedInstanceState恢复数据了");
        }

翻转屏幕,销毁Activity了,单数数据被保存在saveInstanceState中,再次创建横向屏幕Activity时,数据就可以利用saveInstanceState参数进行恢复

以下是利用打断点的方法观察两个key的值

五:Activity的任务栈

启动的Activity会在放在栈中,最先生成的Activity放在栈底,跳转页面启动新的Activity依次往上叠加,返回时符合栈的后进先出原则

小结

如果是一些不是很重要的,不复杂的数据可以直接在onCreate方法中恢复;

还有你想迅速的恢复数据也可以在OnCreate方法中恢复,不同的场景选择使用不同的方法,需要我们自己抉择

非常复杂的恢复数据的代码建议放到onRestoreInstanceState方法中做

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一:翻转屏幕时生命周期变化
  • 二:数据持久化
    • 1:清单中设置屏幕方向
      • (1)landscape
    • 2:configChanges
    • 3:onConfigurationChanged
  • 三:Activity的数据持久化
    • 1:场景引入
    • 2:问题分析
    • 3:onSaveInstanceState
      • (1)效果
    • 4:onRestoreInstanceState
  • 四:saveInstanceState恢复数据
  • 五:Activity的任务栈
    • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档