3.10 为测试重现活动生命周期场景
Daniel Fowler
3.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)。
这些场景造成了不同的生命周期函数执行顺序。在测试时使用这些场景能够确保应用程序正确执行。你可以在实现更多覆盖函数的时候扩展这种技术,它也适用于测试活动中的程序片段的生命周期。