在编程中有一个很重要的概念,就是生命周期。其实世间万物都遵循这个定理。当然在android中,Activity也有其生命周期,了解其生命周期,在之后的Android程序开发中才能如鱼得水。官方给出了一张Activity的生命周期图,如下:
是不是看到上面全是英文而且还带线线圈圈头就已经大了?切勿恐惧。让我来帮你剥开这层神秘的面纱。
Activity生命周期包含了7中方法:onCreate()、onStart()、onResume()、onPause()、onStop()、onRestart()、onDestroy()。即从程序的开始到程序的结束。不同于main()函数为启动入口的其他大多数编程语言,Android 系统会通过调用对应于其生命周期中特定阶段的特定回调方法在 Activity 实例中启动代码。在Android官方教程中是这样介绍Android各个生命周期的执行:
在Activity的生命周期中,系统会按类似于阶梯金字塔的顺序调用一组核心的生命周期方法。 也就是说,Activity生命周期的每个阶段就是金字塔上的一阶。 当系统创建新Activity实例时,每个回调方法会将Activity状态向顶端移动一阶。 金字塔的顶端是Activity在前台运行并且用户可以与其交互的时间点。
当用户开始离开Activity时,系统会调用其他方法在金字塔中将Activity状态下移,从而销毁Activity。 在有些情况下,Activity将只在金字塔中部分下移并等待(比如,当用户切换到其他应用时),Activity可从该点开始移回顶端(如果用户返回到该Activity),并在用户停止的位置继续。
此图示显示,对于用于将Activity朝顶端的“继续”状态移动一阶的每个回调,有一种将Activity下移一阶的回调方法。 Activity还可以从“暂停”和“停止”状态回到继续状态。
需要注意的是:箭头所指向的生命周期流动方向。
在Activity的生命周期中,只有三种状态是静态的,也就是说,Activity只能在三种状态之一下存在很长时间。
- onResume():在这种状态下,Activity处于前台,且用户可以与其交互。(有时也称为“运行”状态。)
- onPause():在这种状态下,Activity被在前台中处于半透明状态或者未覆盖整个屏幕的另一个Activity—部分阻挡。暂停的Activity不会接收用户输入并且无法执行任何代码。
- onStop():在这种状态下,Activity被完全隐藏并且对用户不可见;它被视为处于后台。停止时,Activity实例及其诸如成员变量等所有状态信息将保留,但它无法执行任何代码。
其他状态(“创建”和“开始”)是瞬态,系统会通过调用下一个生命周期回调方法从这些状态快速移到下一个状态。 也就是说,在系统调用 onCreate() 之后,它会快速调用 onStart(),紧接着快速调用 onResume()。
这些方法共同定义 Activity 的整个生命周期。您可以通过实现这些方法监控 Activity 生命周期中的三个嵌套循环:
Activity 的整个生命周期发生在 onCreate() 调用与 onDestroy() 调用之间。您的 Activity 应onCreate() 中执行“全局”状态设置(例如定义布局),并释放 onDestroy() 中的所有其余资源。例如,如果您的Activity 有一个在后台运行的线程,用于从网络上下载数据,它可能会在 onCreate() 中创建该线程,然后在onDestroy() 中停止该线程。
Activity 的可见生命周期发生在 onStart() 调用与 onStop() 调用之间。在这段时间,用户可以在屏幕上看到 Activity 并与其交互。 例如,当一个新 Activity 启动,并且此 Activity 不再可见时,系统会调用 onStop()。您可以在调用这两个方法之间保留向用户显示 Activity 所需的资源。 例如,您可以在 onStart() 中注册一个 BroadcastReceiver 以监控影响 UI 的变化或者绑定一个服务,并在用户无法再看到您显示的内容时在 onStop() 中将其取消注册。在 Activity 的整个生命周期,当 Activity 在对用户可见和隐藏两种状态中交替变化时,系统可能会多次调用 onStart() 和 onStop()。
Activity 的前台生命周期发生在 onResume() 调用与 onPause() 调用之间。在这段时间,Activity位于屏幕上的所有其他 Activity 之前,并具有用户输入焦点。 Activity可频繁转入和转出前台—例如,当设备转入休眠状态或出现对话框时,系统会调用 onPause()。由于此状态可能经常发生转变,因此这两个方法中应采用适度轻量级的代码,以避免因转变速度慢而让用户等待。
下面列出了相同的生命周期回调方法,其中对每一种回调方法做了更详细的描述,并说明了每一种方法在 Activity 整个生命周期内的位置,包括在回调方法完成后系统能否终止 Activity。
注:名为“是否能事后终止?”的列表示:系统是否能在不执行另一行 Activity 代码的情况下,在方法返回后随时能终止承载 Activity 的进程。
有三个方法带有“是”标记:(onPause()、onStop() 和 onDestroy())。由于 onPause() 是这三个方法中的第一个,因此 Activity 创建后,onPause() 必定成为最后调用的方法,然后才能终止进程—如果系统在紧急情况下必须恢复内存,则可能不会调用 onStop() 和 onDestroy()。因此,您应该使用 onPause() 向存储设备写入至关重要的持久性数据(例如用户编辑)。不过,您应该对 onPause() 调用期间必须保留的信息有所选择,因为该方法中的任何阻止过程都会妨碍向下一个 Activity 的转变并拖慢用户体验。
在是否能在事后终止?列中标记为“否”的方法可从系统调用它们的一刻起防止承载 Activity 的进程被终止。 因此,在从 onPause() 返回的时间到onResume() 被调用的时间,系统可以终止 Activity。在 onPause() 被再次调用并返回前,将无法再次终止 Activity。
注:表中的定义属于技术上无法“终止”的 Activity 仍可能被系统终止—但这种情况只有在无任何其他资源的极端情况下才会发生。
注:在所有情况下,系统在调用 onPause() 和 onStop() 之后都会调用 onDestroy() ,只有一个例外:当您从 onCreate() 方法内调用 finish() 时。在有些情况下,比如当您的Activity作为临时决策工具运行以启动另一个Activity时,您可从 onCreate() 内调用 finish() 来销毁Activity。 在这种情况下,系统会立刻调用 onDestroy(),而不调用任何其他生命周期方法。
现在打开Android Studio新建一个项目,然后实现所有Activity生命周期的各个方法,如下:
public class FirstActivity extends AppCompatActivity
{
private static final String TAG = "FirstActivity";
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
Button mBtnJump = (Button) findViewById(R.id.btn_jump);
mBtnJump.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
startActivity(new Intent(FirstActivity.this, SecondActivity.class));
}
});
Log.d(TAG, "onCreate()");
finish();
}
@Override
protected void onStart()
{
super.onStart();
Log.d(TAG, "onStart()");
}
@Override
protected void onResume()
{
super.onResume();
Log.d(TAG, "onResume()");
}
@Override
protected void onPause()
{
super.onPause();
Log.d(TAG, "onPause()");
}
@Override
protected void onStop()
{
super.onStop();
Log.d(TAG, "onStop()");
}
@Override
protected void onDestroy()
{
super.onDestroy();
Log.d(TAG, "onDestroy()");
}
@Override
protected void onRestart()
{
super.onRestart();
Log.d(TAG, "onRestart()");
}
}
然后,如下图:
在2中的下拉框中,选择Edit Filter Configuration,然后如下:
这时候运行你的程序,你会发现,输入下面的内容:
这也证明了上面的说法。
保存Activity状态:
不知道你是否发现,在Activity的生命周期方法中,只有onCreate(Bundle savedInstanceState)方法是带有参数的,从变量名,我们知道“保存单例状态”。
其实Android开发人员意识到,很多时候程序是有自己状态需要保存下来,以免能在某些时刻能及时的恢复。要保存Activity状态,我们需要重写下面那个方法:
@Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
}
第一个方法用于状态的保存,第二个用于状态的恢复。恢复状态也可以在onCreate()方法中,但是建议不要在onCreate()方法中恢复。
首先在onSaveInstanceState()方法中实现数据的保存,代码如下:
@Override
public void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putString("DATA", "I Love Android");
}
a、在onCreate()方法中恢复,代码如下:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
mTvShow = (TextView) findViewById(R.id.tv_showa);
if (savedInstanceState != null)
{
mTvShow.setText(savedInstanceState.getString("DATA"));
}
}
b、在onRestoreInstanceState()方法中恢复,代码如下:
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
mTvShow.setText(savedInstanceState.getString("DATA"));
}
运行程序,触发条件:旋转屏幕。