一个Activity从本质上讲拥有4种状态:
-
运行:
如果当前的activity在前台界面上时(堆栈顶端)。 -
暂停:
如果activity被另一个非全屏活动强占焦点并覆盖时(如弹窗dialog),它将会暂停。一个暂停的活动也是完全活跃的(它的所有的状态和成员信息将会保留,但activity本身将不会再依附于WindowsManager了),在内存极度缺乏的状态会被系统杀死。 -
停止:
如果activity完全被另一个全屏活动遮挡住时,它将会停止。该活动也仍保留全部的状态和成员信息,但将会被隐藏起来不再展示给用户,并且当内存在其他地方被需要时该活动就将会被系统杀死。 -
重启:
如果activity处于暂停或者停止状态,系统将会在内存中终止该活动无论是结束活动或者杀死进程。当它再一次展示给用户时,它必须是完全重启并且恢复到之前的状态。
状态转换
image.png这张图从Activity的起点是从Activity running
开始的
上图中我们可以看到Activity在生命周期状态进行转换的过程中,activity本身是在什么时候调用的onSaveInstanceState()方法与onRestoreInstanceState()方法来进行重要信息的存储与恢复的。因为在蜂巢版本之前onSaveInstanceState()方法只有在activity异常退出时才会调用,所以我们应该在onPause()方法中进行信息持久化存储的操作,在蜂巢之后的版本,生命周期就可以正常的调用onSaveInstanceState()方法来进行信息持久化存储的操作了。
部分实例列举
上面说了一堆Activity生命周期的定义,在实际应用中,我们更倾向于实践运用,所以我会列举部分实例。大家可以给我点个小星星
- 打开activity关闭activity生命周期如下(启动与销毁)
// activity启动
05-24 11:16:44.124 16259-16259/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onCreate
05-24 11:16:44.125 16259-16259/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onStart
05-24 11:16:44.125 16259-16259/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onResume
// activity关闭
05-24 11:16:46.691 16259-16259/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onPause
05-24 11:16:47.038 16259-16259/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onStop
05-24 11:16:47.038 16259-16259/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onDestroy
可以看到正常的启动与关闭Activity不会调用onSaveInstanceState(Bundle)方法与onRestoreInstanceState(Bundle)方法,所以如果要离开该界面时,该界面的重要信息,我们要在onPause()或onStop()方法中进行存储。
- 弹窗(dialog、popupwindow)
[空]
没错,你没看错。是空!因为dialog与popupwindow实际上是一个存在于这个activity上的控件,所以它并不会影响activity本身的生命周期!试想如果你每次弹窗你的activity都要走onPause方法的话,那你的一些存储持久化操作是不是会不停地无更新的存储呢?所以,不要被一些说法误导,如果你不知道,那么就去动手实践。
- 打开Dialog样式的Activity(暂停状态)
// 在Manifest文件中首先设置dialog样式
<activity android:name=".TranslateActivity"
android:theme="@style/Theme.AppCompat.Dialog">
</activity>
// 然后你懂得,我们来打开这个dialog样式的Activity
05-24 16:27:24.964 26913-26913/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onPause
05-24 16:27:25.206 26913-26913/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onSaveInstanceState
// 最后我们关闭这个Activity
05-24 16:27:28.227 26913-26913/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onResume
- 屏幕旋转
05-24 11:24:47.377 16724-16724/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onPause
05-24 11:24:47.378 16724-16724/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onSaveInstanceState
05-24 11:24:47.378 16724-16724/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onStop
05-24 11:24:47.378 16724-16724/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onDestroy
05-24 11:24:47.451 16724-16724/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onCreate
05-24 11:24:47.454 16724-16724/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onStart
05-24 11:24:47.454 16724-16724/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onRestoreInstanceState
05-24 11:24:47.454 16724-16724/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onResume
此处的onSaveInstanceState(Bundle)方法与onRestoreInstanceState(Bundle)方法具体执行时机,当targetSdkVersion小于3时onSaveInstanceState是在onPause方法中调用的,而大于3时是在onStop方法中调用的。而onRestoreInstanceState是在onStart之后、onResume之前调用的。
- 按Home键后再开启app(停止状态)
// 点击home键(菜单键)
05-24 11:50:25.097 17817-17817/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onPause
05-24 11:50:25.407 17817-17817/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onSaveInstanceState
05-24 11:50:25.407 17817-17817/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onStop
// 打开App
05-24 11:51:05.471 17817-17817/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onRestart
05-24 11:51:05.476 17817-17817/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onStart
05-24 11:51:05.476 17817-17817/com.perry.activitylifecycle E/TAG lifecycle: ------>>> onResume
下面我们就结合实例,来演示一下生命周期的几个过程的详细情况。我们新建一个名为lifecycle的项目,创建一个名为LifeCycleActivity的Activity,如下:
package com.scott.lifecycle;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class LifeCycleActivity extends Activity {
private static final String TAG = "LifeCycleActivity";
private Context context = this;
private int param = 1;
//Activity创建时被调用
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate called.");
setContentView(R.layout.lifecycle);
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(context, TargetActivity.class);
startActivity(intent);
}
});
}
//Activity创建或者从后台重新回到前台时被调用
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "onStart called.");
}
//Activity从后台重新回到前台时被调用
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "onRestart called.");
}
//Activity创建或者从被覆盖、后台重新回到前台时被调用
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "onResume called.");
}
//Activity窗口获得或失去焦点时被调用,在onResume之后或onPause之后
/*@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
Log.i(TAG, "onWindowFocusChanged called.");
}*/
//Activity被覆盖到下面或者锁屏时被调用
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "onPause called.");
//有可能在执行完onPause或onStop后,系统资源紧张将Activity杀死,所以有必要在此保存持久数据
}
//退出当前Activity或者跳转到新Activity时被调用
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "onStop called.");
}
//退出当前Activity时被调用,调用之后Activity就结束了
@Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestory called.");
}
/**
* Activity被系统杀死时被调用.
* 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死.
* 另外,当跳转到其他Activity或者按Home键回到主屏时该方法也会被调用,系统是为了保存当前View组件的状态.
* 在onPause之前被调用.
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putInt("param", param);
Log.i(TAG, "onSaveInstanceState called. put param: " + param);
super.onSaveInstanceState(outState);
}
/**
* Activity被系统杀死后再重建时被调用.
* 例如:屏幕方向改变时,Activity被销毁再重建;当前Activity处于后台,系统资源紧张将其杀死,用户又启动该Activity.
* 这两种情况下onRestoreInstanceState都会被调用,在onStart之后.
*/
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
param = savedInstanceState.getInt("param");
Log.i(TAG, "onRestoreInstanceState called. get param: " + param);
super.onRestoreInstanceState(savedInstanceState);
}
}
onCreate()方法中的参数Bundle savedInstanceState 的意义用法
Activity中有一个名称叫onCreate的方法。该方法是在Activity创建时被系统调用,是一个Activity生命周期的开始。可是有一点容易被忽视,就是onCreate方法的参数saveInsanceState。一般的程序开发中,很少用到这个参数。
onCreate方法的完整定义如下:
public void onCreate(Bundle saveInsanceState){
super.onCreate(saveInsanceState);
}
Bundle类型的数据与Map类型的数据相似,都是以key-value的形式存储数据的。
从字面上看saveInsanceState,是保存实例状态的。实际上,saveInsanceState也就是保存Activity的状态的。那么,saveInsanceState中的状态数据是从何处而来的呢?下面我们介绍Activity的另一个方法saveInsanceState。
onsaveInsanceState方法是用来保存Activity的状态的。当一个Activity在生命周期结束前,会调用该方法保存状态。
如下所示:
public void onSaveInsanceState(Bundle saveInsanceState){
super.onSaveInsanceState(saveInsanceState);
}
在实际应用中,当一个Activity结束前,如果需要保存状态,就在onsaveInsanceState中,将状态数据以key-value的形式放入到saveInsanceState中。这样,当一个Activity被创建时,就能从onCreate的参数saveInsanceState中获得状态数据。
状态这个参数在实现应用中有很大的用途,比如:一个游戏在退出前,保存一下当前游戏运行的状态,当下次开启时能接着上次的继续玩下去。再比如:电子书程序,当一本小说被阅读到第199页后退出了(不管是内存不足还是用户自动关闭程序),当下次打开时,读者可能已忘记了上次已阅读到第几页了,但是,读者想接着上次的读下去。如果采用saveInstallState参数,就很容易解决上述问题。
使用例子:
import android.app.Activity;
import android.os.Bundle;
import android.util.Log
public class AndroidTest extends Activity {
private static final String TAG = "MyNewLog";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// If an instance of this activity had previously stopped, we can get the original text it started with.
if(null != savedInstanceState)
{//因为Activity的生命周期原因 ,if 语句放着不一定能执行得到 应该结合实际情况
int IntTest = savedInstanceState.getInt("IntTest");
String StrTest = savedInstanceState.getString("StrTest");
}
setContentView(R.layout.main);
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save away the original text, so we still have it if the activity needs to be killed while paused.
savedInstanceState.putInt("IntTest", 0);
savedInstanceState.putString("StrTest", "savedInstanceState test");
super.onSaveInstanceState(savedInstanceState);
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
int IntTest = savedInstanceState.getInt("IntTest");
String StrTest = savedInstanceState.getString("StrTest");
}
}
小结
文章中我们具体的了解了Activity的7大生命周期与4种本质状态,还有onSaveInstanceState(Bundle)方法与onRestoreInstanceState(Bundle)具体执行时机。便于我们更好的了解与利用Activity中的每一种生命周期方法。
网友评论