写点什么

Android- 系统开发 _ 四大组件篇 ---- 探讨 -Activity- 的生命周期 (1)

用户头像
Android架构
关注
发布于: 刚刚

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


<Buttonandroid:id="@+id/start_normal_activity"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Start NormalActivity" />


<Buttonandroid:id="@+id/start_dialog_activity"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Start DialogActivity" />


</LinearLayout>



修改 MainActivity :


package com.example.marco.activitylifecycletest;


import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;


public class MainActivity extends AppCompatActivity {


public static final String TAG = "MainActivity";private Button startNormalActivity = null;private Button startDialogActivity = null;


@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);startNormalActivity = findViewById(R.id.start_normal_activity);startDialogActivity = findViewById(R.id.start_dialog_activity);startNormalActivity.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, NormalActivity.class);startActivity(intent);}});startDialogActivity.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, DialogActivity.class);startActivity(intent);}});}


@Overrideprotected void onStart() {super.onStart();Log.d(TAG, "onStart");}


@Overrideprotected void onResume() {super.onResume();Log.d(TAG, "onResume");}


@Overrideprotected void onPause() {super.onPause();Log.d(TAG, "onPause");}


@Overrideprotected void onStop() {super.onStop();Log.d(TAG, "onStop");}


@Overrideprotected void onDestroy() {super.onDestroy();Log.d(TAG, "onDestroy");}


@Overrideprotected void onRestart() {super.onRestart();Log.d(TAG, "onRestart");}}


Result

(1)当 MainActivity 第一次被创建时,如下方法被执行:


2018-10-18 04:31:29.071 2526-2526/? D/MainActivity: onCreate2018-10-18 04:31:29.077 2526-2526/? D/MainActivity: onStart2018-10-18 04:31:29.083 2526-2526/? D/MainActivity: onResume



(2)点击 Start NormalActivity 按钮:


2018-10-18 04:33:02.159 2526-2526/com.example.marco.activitylifecycletest D/MainActivity: onPause2018-10-18 04:33:02.745 2526-2526/com.example.marco.activitylifecycletest D/MainActivity: onStop



因为 NormalActivity 已经把 MainActivity 完全遮挡住,因此 onPause() 和 onStop() 方法都会得到执行。


(3)点击 Back 键返回 MainActivity:


2018-10-18 04:35:00.010 2526-2


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


526/com.example.marco.activitylifecycletest D/MainActivity: onRestart2018-10-18 04:35:00.012 2526-2526/com.example.marco.activitylifecycletest D/MainActivity: onStart2018-10-18 04:35:00.014 2526-2526/com.example.marco.activitylifecycletest D/MainActivity: onResume



由于之前 MainActivity 已经进入了停止状态,所以 onRestart() 方法会得到执行,之后又会执行 onStart() 和 onResume() 方法。注意,此时 onCreate() 方法不会执行,因为 MainActivity 并没有重新创建。


(4)点击 Start DialogActivity 按钮:


2018-10-18?04:43:38.006?3555-3555/com.example.marco.activitylifecycletest D/MainActivity:?onPause



通过 Log 可以看到,只有 onPause() 方法得到了执行,onStop() 方法并没有执行,这是因为 DialogActivity 并没有完全遮挡住 MainActivity,此时 MainActivity 只是进入了暂停状态,并没有进入停止状态。


(5)点击 Back 键返回 MainActivity:


2018-10-18?04:50:12.222?3555-3555/com.example.marco.activitylifecycletest D/MainActivity:?onResume



按下 Back 键返回 MainActivity 也应该只有 onResume() 方法会得到执行。


(6)在 MainActivity 界面按下 Back 键退出程序:


2018-10-18 04:51:47.673 3555-3555/com.example.marco.activitylifecycletest D/MainActivity: onPause2018-10-18 04:51:48.013 3555-3555/com.example.marco.activitylifecycletest D/MainActivity: onStop2018-10-18 04:51:48.015 3555-3555/com.example.marco.activitylifecycletest D/MainActivity: onDestroy



依次会执行 onPause()、onStop() 和 onDestroy 方法,最终销毁 MainActivity。

疑问

我们在之前分析 Activity 的生命周期的时候曾经提到过:如果一个活动进入了 onStop (停止)状态,是有可能被系统回收的!

场景

比如我们看以下的场景:


应用中有一个活动 A ,用户在活动 A 的基础上启动了活动 B ,活动 A 就进入了停止的状态,这个时候由于系统内存不足,将活动 A 回收掉了,然后用户按下 Back 键返回活动 A ,会出现什么情况呢?


其实还是会正常显示活动 A 的,但是此时并不会执行 onRestart() 方法了,而是会执行活动 A 的 onCreate() 方法,因为活动 A 在这种情况下会被重新创建一次。


可能这并不会影响正常的功能,但是存在一个特殊情况:如果活动 A 中存在临时数据和状态(比如 A 中有一个文本输入框,我们输入了一些文字,然后启动了 B 活动,如果 A 被 kill 了,在重新回到 A 后,A 活动重新创建,那么数据都丢失了),此时会严重影响用户体验,该怎么办?

策略

其实官方文档给出了解决方案,Activity 中提供了一个 onSaveInstanceState() 回调方法,这个方法可以保证在活动被回收之前一定会被调用,因此我们可以通过这个方法来解决活动被回收时临时数据得不到保存的问题。


onSaveInstanceState() 方法会携带一个 Bundle 类型的参数,Bundle 提供了一系列的方法用于保存数据,比如可以使用 putString() 方法保存字符串,使用 putInt() 方法保存整型数据,依次类推。


每个保存方法需要传入两个参数,第一个参数是键,用于后面从 Bundle 中取值,第二个参数是真正要保存的内容。

Code

我们现在对上面的代码进行修改,在 MainActivity 中添加如下代码将临时数据进行保存:


@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);String tempData = "Something you just typed";outState.putString("data_key", tempData);}



Ok,数据保存好了,那我们应该在哪边进行恢复?


不知道你有没有发现,在 onCreate() 方法中有一个 Bundle 类型的参数。这个参数一般情况下是 null ,但是如果在活动被系统回收之前有通过 onSaveInstanceState() 方法来保存数据的话,这个参数就会带有之前所保存的全部数据,我们只需要再通过相应的取值方法将数据取出即可。


修改 MainActivity 的 onCreate() 方法:


@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.d(TAG, "onCreate");


if (savedInstanceState != null) {String tempData = savedInstanceState.getString("data_key");Log.d(TAG, tempData);}... ...}



通过上面的方法取出值之后再做相应的恢复操作就可以了,比如说将文本内容重新赋值到文本输入框上即可。

附加资料:

Android 进阶



用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android-系统开发_四大组件篇----探讨-Activity-的生命周期(1)