Android开发基础:Activity的生命周期 Activity中的数据保持

目录

一,Activity的生命周期

1.Activity活动栈

 2.Activity状态

3.Activity状态之间的切换

 4.代码实例体验Activity生命周期

二,Activity中的数据保持

1.onSaveInstanceState()


一,Activity的生命周期

1.Activity活动栈

        众所周知,Android中的Activity是可以层叠的,当我们启动一个新的Activity时,就会叠加在旧的Activity上,点击Back销毁Activity,上一个Activity就会重新显示出来,之所以会这样,是因为Android是使用活动栈(也叫返回栈)来管理Activity的。

        每启动一个新的Activity,它就会在活动栈中入栈,并处于栈顶位置,按下Back健销毁Activity后,它就会出栈,下一个Activity就会重新处于栈顶位置,屏幕上显示的总是栈顶的Activity。

 2.Activity状态

Activity在内存中右四种存在状态:

(1)运行状态

        当Activity处于活动栈栈顶时,Activity就处于运行状态。此时的Activity需要和用户进行交互,所以系统尽可能不会回收处于运行状态的Activity。

(2)暂停状态

        当Activity不再处于栈顶位置,但是仍然可见时,就处于暂停状态。例如弹出对话框时,对话框下面的Activity就处于暂停状态。因为暂停状态的Activity仍然可见,所以系统也是尽可能不会回收暂停状态的Activity,除非内存极低的情况,系统才会考虑回收。

(3)停止状态

        当Activity不再处于栈顶位置,并且不可见时,就处于停止状态。因为处于停止状态的Activity可能会被重新启动,所以系统会为这种Activity保存用户状态信息,但当系统内存不够时,会优先杀死该类Activity。

(4)销毁状态

        当Activity从活动栈中移除时就变成了销毁状态。系统会回收该类Activity以保证内存充足。

3.Activity状态之间的切换

        Activity类中定义了七个回调方法,覆盖率Activity生命周期的每一个环节,每当Activity的状态改变时,这些方法就会被调用:

  1. onCreate():创建方法。在Activity第一次被创建时调用,每当我们创建一个新的Activity时,都会重写一次onCreate方法。在这个方法中应当完成加载布局和绑定事件等操作;
  2. onStart():启动方法。在Activity每次由不可见变为可见时调用;
  3. onResume():在Activity准备好与用户交互时调用,此时Activity一定位于活动栈的栈顶,并且处于运行状态;
  4. onPause():暂停方法。在系统准备去启动或者恢复另一个Activity时调用,或者说是当前Activity进入暂停状态之前调用。通常会在这个方法中将一些消耗CPU的资源释放,以及保存一些关键数据。这个方法的执行速度一定要快,否则会影响到新的Activity的使用;
  5. onStop():停止方法。这个方法在Activity完全不可见时调用。
  6. onDestroy():销毁方法。在Activity销毁之前调用。
  7. onRestart();重启方法。在Activity由停止状态变为运行状态之前调用,重启之后Activity重新位于活动栈栈顶,被用户可见;

 

 4.代码实例体验Activity生命周期

我们可以在Activity中重写这七个回调方法,以此来更直观地来体验Activity的生命周期。

(1)分别创建NormalActivity和DialogActivity两个新的Activity,作为要跳转的Activity。其中,DialogActivity作为对话框式的Activity,在AndroidManifest.xml文件中按如下设置:

<activity
    android:name=".DialogActivity"
    android:theme="@style/Theme.AppCompat.Dialog"
    android:exported="true" />

NormalActivity布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="This is NormalActivity"
        android:textSize="25sp"/>

</LinearLayout>

DialogActivity布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="This is DialogActivity"
        android:textSize="25sp"/>

</LinearLayout>

(2)以MainActivity作为主Activity,在布局文件中设置两个按钮,分别用于启动NormalActivity和DialogActivity,并在Activity中给按钮绑定监听器:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_jumpToNormalActivity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="跳转到NormalActivity"
        android:textSize="25sp"/>
    <Button
        android:id="@+id/btn_jumpToDialogActivity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="跳转到DialogActivity"
        android:textSize="25sp"/>
    
</LinearLayout>
//跳转到Normal
btn_jumpToNormalActivity.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        jumpToNormalActivity();
    }
});
//跳转到DialogActivity
btn_jumpToDialogActivity.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        jumpToDialogActivity();
    }
});

private void jumpToDialogActivity() {
    Intent intent = new Intent();
    intent.setClass(this, DialogActivity.class);
    startActivity(intent);
}

private void jumpToNormalActivity() {
    Intent intent = new Intent();
    intent.setClass(this, NormalActivity.class);
    startActivity(intent);
}

(3)最后在MainActivity中重写七个回调方法:

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

    Log.i("msg114514", "MainActivity:onCreate");
}

@Override
protected void onStart() {
    Log.i("msg114514", "MainActivity:onStrat");
    super.onStart();
}

@Override
protected void onRestart() {
    Log.i("msg114514", "MainActivity:onRestart");
    super.onRestart();
}

@Override
protected void onResume() {
    Log.i("msg114514", "MainActivity:onResume");
    super.onResume();
}

@Override
protected void onPause() {
    Log.i("msg114514", "MainActivity:onPause");
    super.onPause();
}

@Override
protected void onStop() {
    Log.i("msg114514", "MainActivity:onStop");
    super.onStop();
}

@Override
protected void onDestroy() {
    Log.i("msg114514", "MainActivity:onDestroy");
    super.onDestroy();
}

接着我们就可以通过日志打印来观察Activity的生命周期了。

(1)首先,启动Activity,观察Logcat可以看到当MainActivity第一次被创建时会依次执行onCreateonStartOnResume三种方法,因为这时Activity刚被创建出来,由不可见变为了可见,并且准备好了与用户进行交互;

(2)点击按钮,启动NormalActivity,可以看到onPauseonStop方法被调用,因为这时另一个Activity被启动,并且MainActivity变为不可见状态,即进入停止状态;

(3)按下Back键返回MainActivity,观察到onRestartonStartonResume方法被调用,因为这时MainActivity由停止状态变为了运行状态,并且重新准备好了与用户进行交互;

(4)点击第二个按钮,启动DialogActivity,此时只有onPause方法被调用,因为MainActivity此时仍能被用户可见,也就是进入了暂停状态;

(5)按下Back键返回MainActivity,发现只有onResume方法被调用,因为之前MainActivity并没有进入停止状态;

(6)最后在MainActivity按下Back键退出程序,此时会依次执行onPauseonStoponDestroy方法,因为MainActivity变为了不可见状态,并且退出程序后MainActivity被销毁;

 至此,我们就完整地体验了一遍Activity的生命周期。

二,Activity中的数据保持

        试想以下这种情况,我们在一个编辑框EditView中编写好了一些内容,但这时发生了一些突发情况使Activity进入了停止状态甚至被销毁(如:不小心点到Back键,有电话突然打进来),从而变得不可见。当我们返回这个Activity时,如果编辑框中的内容消失了,肯定会给用户带来不好的体验,那么我们该如何对这些数据进行保持和恢复呢?

1.onSaveInstanceState()

        Activity提供了一个onSaveInstanceState()回调方法用于保存并恢复一些临时数据,这里的临时数据包括EditText中的内容,视频播放进度等。onSaveInstanceState()方法会携带一个Bundle类型的参数,Bundle提供了一系列的方法用于保存数据。Bundle的保存方法需要传入两个参数,键值和要保存的内容,键值用于从Bundle中取出数据。

public abstract void onSaveInstanceState(Bundle outState);

onSaveInstanceState()的使用具体分为两步:数据的保存与恢复;

(1)数据的保存:在Activity中重写onSaveInstanceState()方法;

@Override
public void onSaveInstanceState(@NonNull Bundle outState, @NonNull PersistableBundle outPersistentState) {
    super.onSaveInstanceState(outState, outPersistentState);
    String text = edt_text.getText().toString();
    outState.putString("edt_text", text);
}

(2)数据的取出:在我们平时一直使用的onCreate方法中有一个Bundle类型的参数savedInstanceState,我们可以通过这个参数来实现对数据的取出,取出时需要判断savedInstanceState是否为空;

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

    if(savedInstanceState != null){
        String text = savedInstanceState.getString("edt_text");
        edt_text.setText(text);
    }
}

        然而实际上对于View我们并不需要进行这些操作,因为Android的View自身已经实现onSaveInstanceState()方法,这些控件本身就具有保存和恢复数据的功能,例如TextView中:

相关推荐

  1. Android学习笔记:activity生命周期

    2024-04-28 09:20:03       37 阅读
  2. AndroidActivity 恢复

    2024-04-28 09:20:03       71 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-28 09:20:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-28 09:20:03       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-28 09:20:03       82 阅读
  4. Python语言-面向对象

    2024-04-28 09:20:03       91 阅读

热门阅读

  1. SQL提升

    2024-04-28 09:20:03       30 阅读
  2. react之state深入浅出

    2024-04-28 09:20:03       28 阅读
  3. 【Python快速上手(六)】

    2024-04-28 09:20:03       32 阅读
  4. 用户注册功能——责任链

    2024-04-28 09:20:03       38 阅读
  5. 模拟电子技术实验(十)

    2024-04-28 09:20:03       33 阅读
  6. 快速了解 git 和 github 是什么,30 分钟速通版

    2024-04-28 09:20:03       25 阅读
  7. 江苏宿迁服务器的优势有哪些?

    2024-04-28 09:20:03       32 阅读