Activity及其生命周期方法

△概述

Activity,是安卓里与用户交互的组件,通俗点说平时用手机的时候看到的一个个界面就是“Activity"所组成的(当然也有可能会是Fragment,这个不在本文讨论),Activity类似一个容器,可以装填布局文件,装填可显示的东西,但Activity本身不具备绘图功能。

△创建"Activity"

要创建一个可用的Activity,一共是有两个方式,在集成开发环境里(如Android Studio)在你想创建Activity的路径哪里右键→new→Activity,很简单的就完成创建了,如果你不想系统来帮你创建,想要自己一步一步来做,那么下面就是步骤:

(1)创建一个Java类,继承Activity,也可继承Activity子类(如FragmentActivity、ListActivity)。

(2)在"Manifest.xml"文件声明你的Activity。

(3)新建一个布局文件,该布局用作该Activity的界面。

(4)重写Activity里的onCreate()方法,调用"setContentView()"方法将布局文件与Activity绑定。

下面看看具体代码:

(1)创建一个Java类,类名叫做"TestActivity",继承Activity,比如这样:

public class TestActivity extends Activity{}

这里只是创建了一个类,其他代码稍后补上。

(2)在"Manifest.xml"文件里面声明你的Activity,像这样子:

<activity android:name=".TestActivity"><!--<intent-filter>--><!--<action android:name="android.intent.action.MAIN" />--><!--<category android:name="android.intent.category.LAUNCHER" />--><!--</intent-filter>-->
</activity>

注意注释掉的部分,如果你的Activity是用作你应用启动时的入口(就是首个Activity),就要写上这几行了,否则的话不要写上。
(3)新建一个布局文件,将它作为Activity界面,这里布局文件的名字是:activity_test,像这样子:

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

这里面只添加一个文本,文本显示一段文字。

(4)重写Activity里的onCreate()方法,调用"setContentView()"方法将布局文件与Activity绑定。

public class TestActivity extends Activity{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);}
}

相比第一步的代码,就是重写一个生命周期方法,然后将布局文件给设置上去。

△启动"Activity"

前面讲了怎么创建一个Activity,那么创建好之后该怎么用呢,现在来看怎么启动Activity。启动Activity也有不同方式,如果一个Activity是应用的入口,那么不用你去启动,系统启动应用那时自动启动,如果一个Activity不是应用入口,那么根据是否需要被启动的"Activity"在结束后返回数据,可以调用两个不同方法启动"Activity",分别是:startActivity()、"startActivityForResult()",我们先来看第一个,关于启动"Activity"并且需要返回数据,我们会在后面谈论。

假设现在有一个"TestActivity",它由一个布局文件:activity_test,布局文件里面有个按钮,点击之后可以启动另外一个"Activity":SecondActivity,activity_test代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/btn_open_second_activity"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="启动SecondActivity"android:textSize="24sp"/>
</LinearLayout>

很简单的只有一个按钮而已。

接下来在"TestActivity"的"onCreate()"方法里面,我们先要找到控件(就是按钮),然后设置一个点击事件响应,通过"Intent"对象指定要启动的Activity,然后调用"startActivity()"方法即可,像这样子:

public class TestActivity extends Activity{private Button openSecondActivity;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);openSecondActivity = (Button)findViewById(R.id.btn_open_second_activity);//调用方法找到按钮openSecondActivity.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(TestActivity.this, SecondActivity.class);startActivity(intent);}});}
}

这样就能启动出"SecondActivity",当然前提是你已经正确创建"SecondActivity"。

△启动"Activity"并且需要返回值

有时候当我们启动另外一个"Activity"是为了让他去完成某个工作,工作完成之后会返回原来的"Activity",而原来的"Activity"需要根据工作完成状况给予用户不同反馈信息,那么此时就需要被启动那个"Activity"能够返回某些数据回来,此时不能再使用"startActivity()"方法,我们需要"startActivityForResult()"方法。

假设现在有两个"Activity":TestActivity,SecondActivity,从“TestActivity"启动"SecondActivity","SecondActivity"里面有一个文本输入框(严格来讲是他的布局文件里有个文本输入框),如果用户在里面有输入任何数据,当"SecondActivity"返回时,告诉“TestActivity"用户已经完成输入,并且将数据送回去,在"TestActivity"里面通过Log打印出输入内容,如果用户什么都没输入,Log里面将会打印"什么东西都没输入“。

这里主要涉及几个方法调用,现在这里简介一下:

(1)onActivityResult:这个方法将在TestActivity里面重写,当我们从"SecondActivity"返回时,系统将会回调这个方法,不论用户有没输入什么东西,都会回调,我们在这个方法里利用标志进行判断,同时也在这里进行数据获取。

(2)startActivityForResult():与"startActivity()"方法类似,也是用来启动一个新的"Activity",不过这个方法告诉系统,当被启动的那一个"Activity"返回时,需要带回一些数据,其实就是告诉系统需要回调"onActivityResult()"方法,如果使用"startActivity()"方法启动新的活动,活动返回时将不会回调"onActivityResult()"方法,这个方法将在"TestActivity"里面重写。

(3)setResult():这个方法就是"SecondActivity()"用来返回数据用的,调用该方法可标识任务是否完成,同时可以携带任务所需要返回的数据。

(4)finish():这个是"Activity"用来结束自己用的方法。

我们先来看看"SecondActivity"布局文件里的代码,文件名字:activity_second,如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><EditTextandroid:id="@+id/et_user_input"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请你输入一些东西"/><Buttonandroid:id="@+id/btn_return"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="返回"/>
</LinearLayout>

一共只有两个控件,一个用来接收输入,一个用来返回到前一个活动。

现在看看逻辑代码:SecondActivity文件,如下:

public class SecondActivity extends Activity{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_second);Button returnButton = (Button)findViewById(R.id.btn_return);final EditText userInput = (EditText)findViewById(R.id.et_user_input);returnButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String userString = userInput.getText().toString();
//                如果用户有输入过什么东西if(userString.equals("")){setResult(RESULT_CANCELED);//其实这里不写也行,默认系统就会传入"RESULT_CANCELED"finish();//关闭当前这个活动}else {
//                    到这说明用户什么都没输入Intent data = new Intent();//Intent对象用来传递数据data.putExtra("userInput", userString);setResult(RESULT_OK, data);//注意这个必须调用,否则"TestActivity"会认为没有返回数据的finish();//关闭当前这个活动}}});}
}

这里只设置了一个点击事件,当按下后,我们获取文本框的内容,然后判断是否有数据,如果没有任何文本,调用"setRdsult()“方法设置结果为"RESULT_CANCELED"标示的是任务取消,我们将没有数据当做取消了任务,当然即使你不调用,系统默认也会返回这个,这里只是为了提高可读性了。如果判断用户是有输入数据,就用Intent对象装着数据,同时设置"RESULT_OK"告诉系统任务已经处理完了,然后不论是否有输入过数据,我们都将"SecondActivity()"返回。

接下来看看"TestActivity"布局文件,文件名:activity_test,如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/btn_start_second_activity"android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center_horizontal"android:text="启动SecondActivity"/>
</LinearLayout>

代码也是非常简单,只有一个用来启动"SecondActivity"用的按钮。

好了接下来就到了核心代码,我们来看"TestActivity"里的代码,尤其需要关注的是"onActivityResult()"方法,像这样子:

public class TestActivity extends Activity {private static int REQUEST_CODE = 0;private static String TAG = "test";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);Button startSecondActivity = (Button)findViewById(R.id.btn_start_second_activity);startSecondActivity.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(TestActivity.this,SecondActivity.class);startActivityForResult(intent,REQUEST_CODE);}});}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if(resultCode == RESULT_OK){//判断"resultCode"看看任务是否完成if(requestCode == REQUEST_CODE){//判断请求码是否能对上Log.i(TAG,data.getStringExtra("userInput"));}}if(resultCode == RESULT_CANCELED){//如果任务被取消了Log.i(TAG,"什么东西都没输入");return;}}
}

首先在"onCreate()"生命周期方法里面,我们为按钮设置了点击事件,用来启动新的活动,这里需要注意的,和前面的启动不同,如果使用"startActivity()"方法启动,返回之后"onActivityResult()"方法将得不到回调,使用"startActivityForResult()"就是需要告诉系统需要回调"onActivityResult()"方法。然后在"onActivityResult()"方法里面,我们需要进行判断,这里面有三个参数都很重要:

(1)首先,resultCode表示被启动的活动是否完成任务,如果值为"Result_OK"表示任务顺利完成,如果值为"RESULT_CANCELED"表示任务被取消了,当然这个返回值由被启动的活动决定。

(2)其次就是requestCode参数了,这个参数代表了请求码,试想一下如果在"TestActivity"活动里面可以启动多个不同活动,"onActivityResult()"方法被回调的时候,怎么知道是由哪个活动返回所导致的回调,只有通过请求码来区分。

(3)一个Intent对象,还记得么,"SecondActivity"里面我们是在一个Intent对象里面,设置了要返回的数据,现在这个对象就传到了这里,我们在这获取数据就可以了。

所有参数介绍完后,来看一下逻辑代码,如果任务顺利完成,再判断下请求码是否能对上,如果对上,就该执行我们的操作了,打印数据。另外一单任务取消,我们也会打印提示。

到此为止,关于如何启动一个活动同时要求返回数据,也基本都介绍完了。

△关闭"Activity"

系统提供这个方法关闭"Activity":finish(),哪个"Activity"调用了它就是关闭哪个"Activity"(就是活动用来自尽用的)。
另外需要补充的一点是,虽然你可以在程序里面手动关闭一个活动,不过,活动的生命应该由系统进行管理,最好不要人为去管理他,而且,被你手动关闭掉的活动,是不可以被回退的,就是不在回退栈里。当然如果像前面的例子那样,那就只能手动去关闭了。

△生命周期

先来一张生命周期全图:

首先单独介绍一下各个生命周期方法:

→onCreate()

当且仅当Activity被创建的时候回调,从Java的角度去理解他,就是对象创建的时候来回调,你应当在这里对窗体做初始化,比如设置布局文件,以及其他一些初始化的设置,当然最重要的就是调用"setContentView()"方法设置布局文件。

→onStart()

当这个方法被回调,说明活动即将被用户所见了,注意了是即将可见,当该方法结束之后,用户就能够看见"Activity"了。

→onResume()

在调用该方法之前,用户已经能够看到“Activity”,在调用了这个方法之后,用户可以与"Activity"进行交互。

→onPause()

一旦调用了该方法,“Activity"即将失去用户焦点(比如临时弹出了一个对话框、或者当你在操作时突然来了一个电话,或者手机进入休眠,都会导致"Activity"失去用户的焦点),需要注意的一点是,如果仅仅回调了该方法,没有回调"onStop()"方法此时,此时用户还是能够看见"Activity",只是不能预知交互而已,只要用户离开活动,他是第一个会被回调的方法。你可以在该方法里保存一些较重要的用户信息,比如用户操作到一半时突然来了一个电话,接完这个电话之后他就不再继续操作,那他之前如果输入某些有用信息,必须保存。

→onStop()

当窗体不再为用户所见(比如有一个新窗体已经完全覆盖原来那个窗体,或者用户回到桌面,或者用户按开机键锁屏),只要你再看不见窗体了,这个方法就会回调。对于那些只是用来更新UI用的资源(比如广播的监听,监听数据变化然后更新UI,像这样的广播就能在该方法里面注销),可以在该方法里面释放,因为用户已经看不到活动了。

→onDestroy()

当活动被销毁的时候,就会回调这个方法,一旦该方法被回调,如无意外(比如内存泄漏就是一个意外),活动对象就会销毁。你需要在这个方法里面释放资源,比如你的活动启动了一个下载任务,你必须在这里释放与下载有关的所有资源(如果你的下载任务需要保持后台下载,那就不用释放这个资源)。

→onRestart()

当活动从后台回到前台,系统就会回调这个生命周期方法,两个操作会导致活动从后台回到前台,一个就是你在某个活动上面直接按下“home”键,然后又重新回到该应用,这时就会回调这个方法。另一个是你在当前活动上面启动另外一个活动,然后又从新的活动返回旧的活动,旧的活动的该方法会被回调。一些跟UI更新相关的操作可能需要在该方法里面进行。

△几个操作所涉及的生命周期方法回调

我们重写所有生命周期方法,然后分别打印一下数据,然后执行几个操作,看看会有什么结果,就能感性体验一下"Activity“生命周期,代码很简单像这样:

public class TestActivity extends Activity {private static String TAG = "test";@Overridepublic void onCreate(Bundle savedInstanceState, PersistableBundle persistentState) {super.onCreate(savedInstanceState, persistentState);Log.i(TAG,"--onCreate--");}@Overrideprotected void onStart() {super.onStart();Log.i(TAG, "--onStart--");}@Overrideprotected void onResume() {super.onResume();Log.i(TAG,"--onResume--");}@Overrideprotected void onPause() {super.onPause();Log.i(TAG, "--onPause--");}@Overrideprotected void onStop() {super.onStop();Log.i(TAG,"--onStop--");}@Overrideprotected void onRestart() {super.onRestart();Log.i(TAG,"--onRestart--");}@Overrideprotected void onDestroy() {super.onDestroy();Log.i(TAG,"--onDestroy--");}
}

我们除了重写以及打印之外,什么事情都没有做。

点击屏幕启动活动:我们看到如下信息:

一个活动完全运行起来,将会回调以下几个方法:onCreate()、onStart()、onResume()。

活动正常打开以后点回退键,我们看到如下信息:

即按下了返回键后,又会回调几个方法:onPause()、onStop()、onDestroy()。

点击屏幕启动活动,这次不点击回退键,点击Home键:

相比起点击回退键,少了一个onDestroy()周期。

让我们再回到最初始的时候,点击屏幕启动活动,这次不点击任何键,而是启动另外一个活动,我看到了如下信息

可以看到这和启动“Activity"然后按下”home"键的情况是一样的。

然后我再从第二个"Activity"回去,我们看到如下信息:

从第二个"Activity"返回,则原来的那个活动将会回调几个方法:onRestart()、onStart()、onResume()。

△生命周期图里面的几个循环

死记"Activity"生命周期方法没有很大意义,你注意到,生命周期图里面有几个循环,可以通过生命周期里的几个循环周期进行学习,同时,理解了这几个循环以后,你会明白我刚才的那些操作为什么会回调对应生命周期。

主要是有三个循环周期:

→entire lifetime(完整周期)

一个"Activity"的完整的生命周期,他是这样子的一个过程:onCreate()→onStart()→onResume()→onPause()→onStop()→onDestroy(),如何得到一个活动完整周期?点击屏幕打开一个活动,什么都不做然后就点返回键,就会回调上面几个生命周期方法,当你第二次再打开活动,又会重新调用onCreate()。可以认为,"onCreate()"方法以及"onDestroy()"方法就是一对的,通过处理这两方法里的代码,你就可以管理好"Activity"创建以及销毁时的任务。

→visible lifetime(可见周期)

该周期内活动对于用户可见,他是这样子的一个过程:

onStart()→onResume()→onPause()→onStop()→onRestart()→onStart(),当被调用onStop(),活动便不再可见了。如果活动又重新回到屏幕上端,会从onRestart()开始回调。什么时候会发生这样的循环?当有一个活动正在运行,你去启动另外一个活动,再从新的活动里面退回,就会发生上述循环。可以认为"onStart()"方法以及"onStop()"是一对的,他们标志着活动对用户可见及不可见。处理好了这两个方法的代码,就能管理好活动在可见和不可见间的逻辑。

→foreground lifetime(前台周期)

处在这个周期里面,当前"Activity"处于其它所有的"Activity"上方,而且获取用户交互焦点。他是这样子的一个过程:onPause()→onResume()。从onResume()到onPause()可能会被频繁调用,因为,当设备进入了休眠状态,或者弹出一个会话,都会调用onPause()。类似的,可以当做"onResume()"方法以及"onPause()"是一对的,他们标志着焦点的得失。

△两个Activity间的生命周期交替

两个"Activity“间的生命周期交替,其实就是当一个"Activity"启动另外的一个"Activity"时,他们两个生命周期执行顺序。这个事情比较简单,这里直接说出结果。例如"Activity"A启动"Activity"D,那么两者生命周期执行顺序:A的"onPause()"→D的"onCreate()"→D的"onStart()"→D的"onResume()"→A的"onStop()"。提出这个过程做什么呢,主要为了以下两点:

(1)如果D里面有一些数据显示,是由A来提交的,比如D要显示数据库的数据,或者"SharedPreferences"文件里的某些数据,这些数据是由A提交的,那么A必须要在"onPause()"方法提交,D才能在他启动时所经历的生命周期里面读取数据,如果A在"onStop()"里才提交,D就读取不到数据。

(2)如果你需要在A离开时进行一些耗时操作,只能将操作放到"onStop()"方法里面,不要放在"onPause()"方法里面,因为如果"onPause()"方法一直没执行完,新的"Activity"跟本就启动不起来。当然最好的情况是,别在活动任何一个生命周期方法里面执行耗时操作。

△Activity数据保存与恢复

为什么要进行数据保存以及恢复

正常情况下结束掉"Activity",不用考虑状态保存与恢复的问题,对于意外被结束的"Activity",就要考虑这个问题。那么什么是意外被结束掉的"Activity"?最典型的一个例子就是屏幕方向变化。作为用户,如果我将屏幕方向横竖变化,对我而言,只是转了一个方向,界面上的所有东西(我已经输入的数据)应该原封不动地在哪里。很可惜的,对于安卓系统而言,如果屏幕发生旋转,他会将"Activity"重建。也就是说对于一个被旋转的"Activity",他会发生如下生命周期:onPause()→onStop()→onDestroy()→onCreate()→onStart()→onResume()。那么现在的问题是,如果我在活动上面按返回键,数据丢失是正常的,作为用户我能理解,但是如果我就只是转个屏幕,然后东西就都没了,这是我不能理解的。对于这么一个问题,就需要开发人员处理了。这就是意外结束的"Activity"需要进行状态保存以及恢复。
先来一张官网上的图片:

数据保存与恢复的过程及其关键方法

从图里面可以看到,数据保存与恢复的两个主要的负责人:onSaveInstanceState(Bundle)方法、onRestoreInstanceState(Bundle)方法(或者onCreate()方法)。正常情况下,"onSaveInstanceState()"方法以及"onRestoreInstanceState()"方法和活动的生命周期并无特别关联,不论怎么操作活动都不引发这两方法回调。但是当你对活动的操作导致活动意外结束,那么这两方法就会被回调了。从图里面可以看到这两方法被回调的时机,确切地说,如果"onSaveInstanceState()"会被回调,他将会在"onStop()"方法之前被回调,至于他和"onPause()"谁先回调,说不准的。而"onRestoreInstanceState()"方法,则在用户重新回到活动那是回调。
根据我们所描述的内容,以屏幕旋转为例子,状态保存及恢复的方法如下:重写"onSaveInstanceState()"方法,将数据保存到Bundle对象里面,然后重写"onRestoreInstanceState(Bundle)"方法,在方法里判断一下所传入的Bundle对象是否为空,如果不为空,说明你在"onSaveInstanceState()"方法里面曾经做过数据保存,只要取出数据然后恢复即可。让我们来看个例子体验一下。
我们放置两个控件:Button+TextView,每次点击按钮之后,记录他的点击次数,并显示到TextView那里。现在看看界面代码,界面名字:activity_test,如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><TextViewandroid:id="@+id/tv_click_num"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="24sp"android:gravity="center_horizontal"android:text="你点击了0次按钮"/><Buttonandroid:id="@+id/btn_be_click"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="点我"/>
</LinearLayout>

就是两个控件而已。我们在活动"onCreate()"方法里面找到控件并且设置点击事件。如下:

    private TextView clickNumTextView;//这个是界面里面的TextViewprivate Button clickBtn;//这个是界面里面的Buttonprivate int num;//这个成员变量用来保存点击次数@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);
//        找到项对应的控件clickNumTextView = (TextView)findViewById(R.id.tv_click_num);clickBtn = (Button)findViewById(R.id.btn_be_click);
//        设置点击事件监听clickBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {
//                记录并且显示点击次数num = num+1;clickNumTextView.setText("你点击了"+num+"次按钮");}});}

然后重写我们说的两个关键方法,首先"onSaveInstanceState()"如下:

    @Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);outState.putInt("num",num);//通过Bundle对象保存数据}
可以看到,我们使用方法里面传进来的"Bundle"对象进行数据保存,然后重写"onRestoreInstanceState()"方法进行数据恢复,如下:
    @Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {super.onRestoreInstanceState(savedInstanceState);
//        如果为空表示没有保存数据,直接返回if(savedInstanceState==null){return;}
//        取出并且显示被保存的数据clickNumTextView.setText("你点击了"+num+"次按钮");}

现在来看整个活动完整代码:

public class MainActivity extends Activity {private TextView clickNumTextView;//这个是界面里面的TextViewprivate Button clickBtn;//这个是界面里面的Buttonprivate int num;//这个成员变量用来保存点击次数@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);
//        找到项对应的控件clickNumTextView = (TextView)findViewById(R.id.tv_click_num);clickBtn = (Button)findViewById(R.id.btn_be_click);
//        设置点击事件监听clickBtn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {
//                记录并且显示点击次数num = num+1;clickNumTextView.setText("你点击了"+num+"次按钮");}});}//    将点击的次数保存到"Bundle"对象里面@Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);outState.putInt("num",num);//通过Bundle对象保存数据}//    取出被保存的数据@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {super.onRestoreInstanceState(savedInstanceState);
//        如果为空表示没有保存数据,直接返回if(savedInstanceState==null){return;}
//        取出并且显示被保存的数据clickNumTextView.setText("你点击了"+num+"次按钮");}
}
这个例子到这就结束了,不过有个东西要说明下。我们说过这个是活动在意外情况下被结束时,用来进行数据保存及恢复的方法,但是这个绝对不是专门用来进行数据保存用的方式。如果你的活动不是意外结束,比如就是用户点了“返回”按键,这些方法根本不会被回调的。绝对不能依靠前述两个方法用来保存数据。对于那些很重要的必须进行保存用的数据(存在数据库或者是"SharedPreferences"文件里面存的数据),能依靠的就只有在"onPause()、:"onStop()"这类方法里面保存,不要完全去依赖"onSaveInstanceState()"方法或者"onRestoreInstanceState()"方法来做数据保存。这里需要强调的是,只有意外结束活动才能使用这个方式保存数据。至于有多少情况是“以外”情况,这个不在这里逐个列举,只要记住屏幕旋转是最典型,同时也是最容易拿来做测试用的情况。

关于活动数据保存以及恢复,也讲完了。

Activity及其生命周期小结相关推荐

  1. 【Android Activity】Activity的生命周期

    知识点 一.Activity的生命周期 1. 生命周期回调 onCreate:表示Activity正在被创建.生命周期的第一个方法,当打开一个activity时首先回调这个方法.在这个方法中一般做一些 ...

  2. Activity的生命周期是谁调用的?

    我们知道Activity的生命周期包括onCreate.onStart.onResume.onRestart.onStop.onDestory.onSaveInstanceState.onRestor ...

  3. 横竖屏切换时候Activity的生命周期

    曾经遇到过一个面试题,让你写出横屏切换竖屏Activity的生命周期.现在给大家分析一下他切换时具体的生命周期是怎么样的: 1.新建一个Activity,并把各个生命周期打印出来 2.运行Activi ...

  4. Android开发---Activity的生命周期

    在Android开发中,第一步学习的应该是最基础的东西,即Activity的声明周期,相信Activity对于从事Android开发的朋友都很熟悉,这里作者不多做解释.Android的生命周期可以用如 ...

  5. Android组件系列----Activity的生命周期

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  6. Activity的生命周期理解

    Activity拥有4个基本状态: 活动状态:当前Activity位于前台,可以看见也可以获得焦点,可以接受用户输入的 暂停状态:其他Activity位于前台,该Activity依然可见,但是不能获得 ...

  7. android的应用入口点函数,android 没有main函数,怎么找到程序执行入口呢?以及activity主要生命周期的方法说明...

    android应用程序,由一到多个Activity组成.每个Activity没有很紧密的联系,因为我们可以在自己的程序中调用其它Activity,特别是调用自己的代码之外生成的Activity,比如a ...

  8. Android学习笔记系列四2 —— Activity的生命周期

    2019独角兽企业重金招聘Python工程师标准>>> 启动一个Activity 使用startActivity(Intent intent). intent指定了你想要启动的act ...

  9. activity 生命周期_从0系统学Android-2.4 Activity 的生命周期

    本系列文章,参考<第一行代码>,作为个人笔记 更多内容:更多精品文章分类 本系列持续更新中-. 2.4 Activity 的生命周期 掌握 Activity 的生命周期对于开发者来说是非常 ...

最新文章

  1. Delphi与JAVA互加解密AES算法
  2. iOS 日期格式的转换
  3. [转] 用Diff和Patch工具维护源码
  4. mysql 安装测试ok_tpcc-mysql安装测试与使用的实例教程
  5. linux压缩命令(二)bzip2总结
  6. python3 zip命令_在打包为zip文件的应用程序上从命令行运行pdb?
  7. vscode为python文件添加模板
  8. java调用dao_Servlet里面一调用Dao里的某个方法
  9. img图片实现垂直居中
  10. ECMALL模板解析机制.MVC架构分析及文件目录说明.二次开发指南手册
  11. 团队管理的一些基本要点
  12. 陈敏 Java课设实验报告
  13. 导入FontForge生成字体
  14. php seekdir,perl 模式匹配总结和shell命令调用方法 (zz)
  15. 使用 Ruby 开发代码生成器
  16. 论语 尧曰篇(笔记)
  17. WinDbg 常用指令
  18. 微信小程序:本地存储数据
  19. 传统企业如何建设B2C平台做网络营销?
  20. 【技术美术】千人千面如何炼成 技术讲解捏脸系统设计原理

热门文章

  1. 《深入解析Windows操作系统》之系统机制
  2. PHP服务器端API原理及示例(接口开发)
  3. java多用户商城系统架构之第一篇——总的介绍
  4. win10计算机右键属性打不开,win10电脑系统属性打不开的解决方法
  5. 银行软件测试工作总结
  6. 量子能--下一代能源革命
  7. vscode之 wget下载文件报错:ERROR: cannot verify data.vision.ee.ethz.ch‘s certificate
  8. android 删除插件,Android手机如何添加删除桌面图标和插件
  9. 天九共享集团:为创业者提供坚实的信用背书
  10. linux认证版本,LPI Linux认证考试教程 中文PDF最新版