Daniel Fowler3.10.1 问题应用程序应该适应活动生命周期。开发人员必须知道如何重现不同的生命周期场景。3.10.2 解决方案利用日志获得对活动生命周期的全面了解,就能更容易地为测试重现生命周期场景。3.10.3 讨论Android是为了移动的生活方式而设计的,在这种方式下,用户忙于多种工作:打电话、检查邮件、发送SMS信息、参与社交网络、拍照、访问互联网、运行应用程序等,甚至完成某些工作!因此,移动设备可能有多个应用程序,从而在内存中加载许多活动。前台应用及当前活动可能在任何时刻被打断和暂停。暂停的应用程序和活动也可能从内存中删除,为新启动的应用程序释放内存。应用程序的生命周期不受其控制,因为Android操作系统负责启动、监控、暂停、恢复和删除应用的活动。但是,活动知道发生了什么,因为在活动实例化、隐藏和删除时,会调用各种函数,这使得活动能够跟踪操作系统对应用程序所进行的操作,我们在攻略1.6中已经讨论过这一点。因为上述原因,应用程序开发人员熟悉活动启动时调用的函数:onCreate(Bundle savedInstanceState){...};onStart(){...};onResume(){...};以及活动暂停并从内存中删除(销毁)时调用的函数:onPause(){...};onStop(){...};onDestroy(){..};打开攻略1.4中的程序,就可以看到以上函数的运行情况。然后,在主活动类中,覆盖上述的6个函数,调用其超类版本。添加Log.d()调用传递应用程序名称和被调用的函数,代码参见例3-7。例3-7:生命周期日志
public class Main extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.d("MyAndroid", "onCreate"); } @Override public void onStart() { super.onStart(); Log.d("MyAndroid", "onStart"); } @Override public void onResume() { super.onResume(); Log.d("MyAndroid","onResume"); } @Override public void onPause() { super.onPause(); Log.d("MyAndroid","onPause"); } public void onStop() { super.onStop(); Log.d("MyAndroid","onStop"); } public void onDestroy() { super.onDestroy(); Log.d("MyAndroid","onDestroy"); } }运行程序。显示LogCat视图查看调试信息。调试信息在Dalvik Debug Monitor Server(DDMS)视图中默认可见,你也可以通过Window菜单选项打开它。单击Window→Show View→Other,展开Android并选择LogCat,LogCat视图出现在底部的选项卡中。单击Eclipse右上角的DDMS按钮可以打开DDMS视图,如图3-16所示。
LogCat视图将出现在底部的选项卡中。如果该视图不可见,使用前面提到的Window菜单方法,或者选择Window→Reset Perspective。你可以从Eclipse中拖动选项卡,将LogCat拖离所在的窗口。启动程序之后,你可以看到添加到启动函数中的3条调试信息(见图3-17)。 按下Back按键时,你将看到3条卸载信息(见图3-18)。 添加一个LogCat过滤器可以仅查看来自应用程序的信息。单击LogCat屏幕右上角的绿色加号。为过滤器取名,并在Log Tagtag字段中输入MyAndroid(见图3-19)。 现在,LogCat显示一个新的选项卡,其中只包含明确地从应用程序中发送的信息(见图3-20)。 可以单击右上角的图标(带有红×的页面),清除LogCat输出。这样有助于在执行查看更多信息的操作之前得到干净的表单。 为了查看程序暂停时调用的函数,在MyAndroid程序之上再打开一个应用程序。首先添加onRestart()函数和调试信息。 @Override public void onRestart() { super.onRestart(); Log.d("MyAndroid","onRestart"); }运行该程序,单击Home按钮,然后从设备(或者模拟器)上再次启动程序。LogCat显示通常的启动函数顺序;然后,当单击Home按钮时,运行onPause()和 onStop(),但是没有运行onDestroy()。该程序没有结束,但是处于休眠状态。当程序再次运行,它并没有重新加载,所以没有运行onCreate(),而是调用onRestart()。在设备或者模拟器上再次运行该程序,然后进入Manage Applications(应用程序管理)菜单,方法是Settings(设置)→Applications(应用程序),选择程序,并单击Force Close(强制关闭)按钮。从设备(或者模拟器)再次启动程序。调用通常的启动函数,然后活动“休眠”。由于第二个实例运行,没有看到onDestroy()。在本攻略中,我们讨论了如下不同的生命周期场景:正常启动,然后结束。启动、暂停再重新启动(见图3-21)。
启动、暂停、强制从内存中删除,然后再次启动(见图3-22)。 这些场景造成了不同的生命周期函数执行顺序。在测试时使用这些场景能够确保应用程序正确执行。你可以在实现更多覆盖函数的时候扩展这种技术,它也适用于测试活动中的程序片段的生命周期。