Activity的重建(recreate)与恢复

关于Activity的重建我们可以从以下三个方面去了解:

Activity会出现重建的三种情况:

1. 系统内存不足:android系统会杀死一个进程,在系统需要释放内存的时候,而位于进程内的activity就会被销毁。在用户重新回到这个Activity的时候,这个Activity 就会被重建。

2. Configuration Change(Activity横竖屏切换,进入多窗口模式):在横竖屏切换时,系统为了调整布局适应新的配置,在默认情况下会重建Activity。

3. 调用Activity的oncreate()方法:主题切换时可以调用oncreate重建Activity使新的主题生效。

Activity在重建时的状态变化:

首先我们通过一段简单代码来看一下重建过程Activity的状态:

public class LifeCycleActivity extends AppCompatActivity {

    private static final String TAG = LifeCycleActivity.class.getName();

    private static final String KEY_TEST = "test";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_life_cycle);
        TextView tvContent = findViewById(R.id.tv_content);
        if (savedInstanceState == null) {
            Log.i(TAG, " ---> first time onCreate");
        } else {
            Log.i(TAG, " ---> recreate");
            String test = savedInstanceState.getString(KEY_TEST);
            tvContent.setText(test);
        }

        findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                recreate();
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG, " ---> onStart");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, " ---> onResume");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, " ---> onPause");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, " ---> onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, " ---> onDestory");
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i(TAG, " ---> onRestart");
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putString(KEY_TEST, "testing");
        Log.i(TAG," ---> onSaveInstanceState");
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        String test = savedInstanceState.getString(KEY_TEST);
        Log.i(TAG, " ---> onRestoreInstanceState");
    }
}

App运行之后切换横竖屏,通过上面代码实验得到的结果是:

I/com.zj.activitylifecycle.LifeCycleActivity:  ---> first time onCreate
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onStart
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onResume
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onPause
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onSaveInstanceState
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onStop
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onDestory
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> recreate
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onStart
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onRestoreInstanceState
I/com.zj.activitylifecycle.LifeCycleActivity:  ---> onResume
在进入paused状态之后,会调用onSaveInstanceState去保存需要的数据状态,在重建的时候可以在onCreate和onRestoreInstanceState中的参数去获取销毁前保存的数据。

Activity的状态恢复

在一些场景下你的Activity是被正常的销毁,当用户按下返回键,或者Activity内部调用finish()方法,在用户和系统的观念中这个Activity的实例是已经不再需要了。在这些场景下Activity的销毁,你不需要做其他额外的工作。但是如果系统销毁Activity是由于系统的限制(configuration和memory pressure), 这种情况下为了保持用户用户体验,我们需要在用户回到Activity时恢复Activity的状态。这种情况下,尽管Activity的实例已经消失,但是系统会记住Activity的实例曾经存在过。如果用户尝试重新回到Activity的时候,系统会使用Activity在被销毁时保存的状态和数据去创建一个新的Activity实例。

系统用来恢复之前的状态而保存的数据叫做instance state,是存储在Bundle中的键值对集合。默认情况下,系统使用Bundle来存储layout中View的状态(例如在EditText中输入的信息),确保Activity重建时能恢复到之前的状态。你也可以用来存储一些你想要在重建时恢复的信息,例如一些成员变量的值和用户的进度信息。

ps:为了确保系统能够恢复你Activity中View的状态,每一个View都需要有一个独特的id(通过 android:id 属性定义)。

但是Bundle不适合用来保存大量的数据,因为数据在保存时需要在主线程中序列化,会消耗系统内存。如果有比较多的数据需要保存时可以结合本地存储。

View的状态系统会自动保存我们不需要做额外的事情,但是你有其他数据需要存储时可以重写onSaveInstanceState方法:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString(KEY_TEST, "testing");
    Log.i(TAG," ---> onSaveInstanceState");
}

数据在onCreate或onRestoreInstanceState中恢复:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_life_cycle);
        TextView tvContent = findViewById(R.id.tv_content);
        if (savedInstanceState == null) {
            Log.i(TAG, " ---> first time onCreate");
        } else {
            Log.i(TAG, "recreate");
            String test = savedInstanceState.getString(KEY_TEST);
            tvContent.setText(test);
        }

        findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                recreate();
//                Intent intent = new Intent(LifeCycleActivity.this, SecondActivity.class);
//                startActivity(intent);

            }
        });

    }
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    String test = savedInstanceState.getString(KEY_TEST);
    Log.i(TAG, "onRestoreInstanceState");
}

onSaveInstance方法并不是每次都会在onPause之后被调用,如果Activity是被明确的close(用户点击返回按钮)或者调用finish时,onSaveInstanceState不会被调用。

如果需要持久化数据,如保存到preference或database,最佳选择是Activity在前台的时候去保存,如果没有这样的机会你可以在onStop方法中去保存。

 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在Android上重启一个Activity,可以使用 Intent 和 finish() 方法。 例如: ``` Intent intent = new Intent(CurrentActivity.this, CurrentActivity.class); finish(); startActivity(intent); ``` 首先,创建一个新的 Intent 对象,并将当前 Activity 作为上下文传入。 然后调用 finish() 方法结束当前 Activity,最后调用 startActivity(intent) 方法重新启动该 Activity。 ### 回答2: 在Android中,可以通过以下几种方式来重启Activity。 1. 使用Intent重新启动Activity:可以通过创建一个新的Intent对象,并将原Activity的类名和其他需要传递的数据传递给新的Intent,然后调用startActivity()方法来启动新的Activity,并使用finish()方法来销毁原Activity。 2. 使用FLAG_ACTIVITY_CLEAR_TOP标志重新启动Activity:可以在Intent中设置FLAG_ACTIVITY_CLEAR_TOP标志,然后调用startActivity()方法来启动新的Activity。这个标志会检查Activity的任务栈,如果需要启动的Activity已经在任务栈中存在,那么会将该Activity之上的所有Activity都销毁掉,然后重用已存在的Activity,并将其置于栈顶。 3. 使用Recreate()方法重启Activity:在Android 3.0及以上版本中,可以通过调用Activity的recreate()方法来重启Activity。这个方法会销毁当前的Activity,然后重新创建一个新的Activity,并将其置于栈顶。 需要注意的是,以上这些方法都会导致Activity的生命周期方法被重新调用,如onCreate()、onStart()、onResume()等,所以在处理重启逻辑时,需要注意保存和恢复Activity的状态。 另外,可以根据具体的需求选择合适的重启方式,如是否需要传递数据、是否需要清空任务栈等。根据不同的场景,选择合适的方法可以更好地实现Activity的重启功能。 ### 回答3: 在Android中,我们可以通过调用`startActivity()`方法来启动一个新的Activity。当我们希望重新启动当前Activity时,有以下几种常见的方法。 1. 使用`Intent.FLAG_ACTIVITY_CLEAR_TOP`标志: 通过在启动新Activity时设置`Intent.FLAG_ACTIVITY_CLEAR_TOP`标志,我们可以清除当前Activity之上的所有Activity。这样,在新的Activity启动后,原来的Activity会被销毁并被新的Activity覆盖。代码如下: ```java Intent intent = new Intent(this, NewActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); ``` 2. 使用`Intent.FLAG_ACTIVITY_NEW_TASK`标志: 通过在启动新的Activity时设置`Intent.FLAG_ACTIVITY_NEW_TASK`标志,我们可以在新的任务栈中启动新的Activity。这样,原来的Activity会被销毁,并且返回到主界面,而新的Activity将会在新的任务栈中启动。代码如下: ```java Intent intent = new Intent(this, NewActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); finish(); ``` 3. 通过重新启动Activity: 通过重新调用`onCreate()`方法和`onStart()`方法,我们可以重新启动当前Activity。代码如下: ```java Intent intent = getIntent(); finish(); startActivity(intent); ``` 以上是三种常见的Android重启Activity的方法,开发者可以根据具体的需求选择合适的方法来实现重启。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值