3.7 组件生命周期
我们在前面提到过组件的生命周期。例如,onCreate操作会启动一个应用。组件生命周期有两个用途:它有助于每个应用的内存或堆空间被有效利用,并且能够确保保存和恢复整个进程的状态,从而使得Android系统能够运行比实际内存容量更多的应用。
活动生命周期
最复杂的组件生命周期是活动的生命周期。这里我们将通过图表描述它,看看这些状态变化在代码层面是如何处理的。在图3-5中,可以看到活动生命周期的状态和状态转换。处理生命周期状态转换的核心因素在于选择需要实现的那一种生命周期回调,并了解什么时候执行这些回调。
在第11章中,我们将进一步深入探讨这个话题。现在,我们来看看Activity类的两种方法。在运行时调用第一种方法通知应用保存其状态,调用第二种方法支持新的Activity实例恢复已经销毁的Activity生命周期的状态。下面这段代码摘自第11章,在第11章可以看到整个程序,包括所指向的成员变量:
当运行时系统要销毁某个活动但是希望能够在后期重新恢复其状态时,会调用activity的onSaveInstanceState方法。这一点和执行状态转换的其他生命周期方法有显著区别。举个例子,如果一个活动显式地结束了,其状态就不再需要恢复,即使需要传递当前的paused状态,调用其onPause方法。正如之前的代码片段所示,在onSaveInstanceState方法中要做的是保存用户在后期会用到的状态,做到该活动的状态销毁和恢复对于后期使用是透明的:
···
@Override
protected void onRestoreInstanceState(Bundle savedState) {
super.onRestoreInstanceState(savedState);
// Restore state; we know savedState is not null
String answer = savedState.getString("answer");
// ...
Log.i(TAG, "onRestoreInstanceState"
+ (null == savedState ? "" : RESTORE) + " " + answer);
}
···
当重新创建已经销毁的活动时,会调用onRestoreInstanceState方法。因此,会运行该应用活动的一个新的实例。该应用活动的前一个实例中通过onSaveInstanceState方法所存储的数据,会通过onRestoreInstanceState方法传递给新的实例。
你可能会认为活动有如此复杂的生命周期,并且堆使用需求限制很严格,Android的活动生命周期在Android应用代码中应该很清晰,需要花费很多时间和精力来满足活动生命周期需求。然而,实际上并非如此。
在很多Android代码中,尤其在小的Android实例中,很少实现生命周期回调功能。这是由于Activity父类会处理生命周期回调,即类View及其子类,并且保存它们的状态,如图3-6所示。这意味着在很多情况下,Android的View类会提供所有必要的用户接口功能, Android应用不需要显式处理大多数的生命周期回调。
这看起来确实很不错,因为它使得Android编程变得简单多了。你不需要编写任何代码,就可以轻松实现如图3-6所示的内容。然而,它也存在不足,因为它会导致编程人员忽略活动的生命周期,直到某天发现自己的代码存在一堆bug变得一团糟。这也是在这里强调生命周期的原因,这也是在第11章要说明如何处理所有的生命周期回调并记录日志的原因。要充分意识到活动生命周期可能是在预防那些难以诊断的bug中所能够做到的最重要的事情。