4.1 什么是生命周期
想要真正地理解Cordova应用开发的内涵,首先需要理解什么是生命周期。这在字面上其实非常容易理解,一个应用从开始运行→被手机加载→应用被退出之间的过程就称之为一个生命周期。为了使读者更容易理解,本节将以Android原生SDK中Activity类的生命周期结合Eclipse中的LogCat调试工具进行实战讲解。
4.1.1 Activity的生命周期
先仔细地观察图4-1的内容,这是谷歌官方给出的Activity生命周期流程图,它包括了一个安卓应用从被创建到结束时所经历的各种事件。下面是Activity生命周期中所经历的各个过程。
图4-1 Activity的生命周期
(1)启动Activity:系统将调用onCreate方法创建新的Activity对象,然后依次调用onStart方法和onResume方法使刚刚创建的Activity进入运行状态。
(2)暂停状态:当前的Activity被其他的Activity覆盖或手机锁屏,原Activity被放入后台,系统将调用onPause方法使Activity进入暂停状态。
(3)恢复状态:当处于暂停状态的Activity重新被运行时,系统将调用onResume方法使之重新回到运行状态。
(4)后台状态:当用户点击Home键返回主屏,Activity被保存在后台,系统将先调用onPause方法再调用onStop方法使Activity处于暂停状态。
(5)返回状态:当用户重新打开Activity时,系统会先调用onRestar方法再调用onStar方法,最后调用onResume方法使应用返回到运行状态。
(6)当前Activity处于被覆盖状态或者后台不可见状态,此时系统内存不足,进程中断,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。
(7)用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。
经过一番解释之后,相信读者已经能够看懂图4-1中的内容了,可是为什么要这样做呢?
众所周知,智能机相对于非智能手机的一个重要特点就在于,智能机具有“后台”,能同时运行多个程序。比如可以一边挂着QQ,一边听音乐,同时浏览微博中的内容,而这时如果有人打电话进来,手机能够自动切换未接电话的界面,而这一切都是通过生命周期来实现的。
4.1.2 通过实例体验Activity的生命周期
以上介绍了Activity生命周期中的各个过程,本小节将以一个简单的实例来体验Activity生命周期中的各个事件。
在Eclipse中新建一个Android工程,命名为example4_1,修改其MainActivity类中的内容如范例4-1所示。
【范例4-1】Activity生命周期的演示。
01 //此处省略若干个导入文件,由Eclipse自动生成 02 public class MainActivity extends Activity { //类MainActivity继承类 Activity 03 String TAG="Activity生命周期事件"; 04 @Override 05 protected void onCreate(Bundle savedInstanceState) { 06 super.onCreate(savedInstanceState); 07 setContentView(R.layout.activity_main); 08 Log.e(TAG, "启动onCreate事件"); 09 } 10 @Override 11 protected void onDestroy() { //重写onDestroy事件 12 // TODO Auto-generated method stub 13 super.onDestroy(); 14 Log.e(TAG, "启动onDestroy事件"); //在LogCat中显示记录 15 } 16 @Override 17 protected void onPause() { 18 // TODO Auto-generated method stub 19 super.onPause(); 20 Log.e(TAG, "启动onPause事件"); 21 } 22 @Override 23 protected void onRestart() { 24 // TODO Auto-generated method stub 25 super.onRestart(); 26 Log.e(TAG, "启动onRestart事件"); 27 } 28 @Override 29 protected void onResume() { 30 // TODO Auto-generated method stub 31 super.onResume(); 32 Log.e(TAG, "启动onResume事件"); 33 } 34 @Override 35 protected void onStart() { 36 // TODO Auto-generated method stub 37 super.onStart(); 38 Log.e(TAG, "启动onStart事件"); 39 } 40 @Override 41 protected void onStop() { 42 // TODO Auto-generated method stub 43 super.onStop(); 44 Log.e(TAG, "启动onStop事件"); 45 } 46 }
运行之后即可看到在LogCat窗口中显示出如图4-2所示的内容。
图4-2 Activity启动时所经历的事件
提示
可以通过设置过滤器来过滤LogCat中的信息,使之只显示与该Activity有关的记录,如图4-3所示,过滤后的内容如图4-4所示。
图4-3 利用Tag标签过滤LogCat中的信息
图4-4 过滤后的LogCat窗口
回过头来再看以上对启动Activity的描述,要启动一个Activity需要经历onCreate、onStart、onResume三个事件,在图4-4中可以确认这一点。可以通过对手机的进一步操作来验证以上的内容,比如点击Home键或返回键来观察LogCat中的日志记录。
在Eclipse的代码编辑区域点击鼠标右键,在弹出的菜单中,依次选择Source|Override methods命令可以看到一些其他的事件,如图4-5所示。
图4-5 Activity中的一些其他事件
这类事件大多对应着应用的某一特定操作或错误。比如事件OnTitleChanged就是在应用的标题被修改时由系统所发出的事件;再比如听音乐,音乐播放到1分50秒时突然打进来一个电话,系统就会对播放器的Activity使用onPause方法,同时启动一个接电话的Activity,当用户接完电话后则又会通过onRestar方法和onStar方法返回音乐播放界面,并调整音乐播放进度为1分50秒。
4.1.3 Cordova的生命周期
以上通过一个简单的例子演示了Activity的生命周期中事件的作用,即软件应用过程中发生了某操作后由系统产生的某种响应。与之类似的是,Cordova中也有着生命周期和事件的概念。
在Cordova中,系统通过JavaScript截获来自于硬件的信息。目前,Cordova可以处理包括网络、电量、音量、按钮等方面的信息。当使用Cordova编写的应用处于运行状态时,如果系统接收到了某种信号(比如用户按下了音量键),那么系统就能够做出相应的反馈。
注意
Cordova的生命周期只包括应用在屏幕中运行的一部分,当应用被暂停和重新运行时有pause事件和resume事件来与它们对应。
Cordova的整个生命周期可以划分成15种不同的事件,如表4-1所示。
表4-1 Cordova生命周期中的事件
看上去似乎有些混乱,既不是按照字母顺序也没有按照单词长度,但是按照表格右侧的解释来看却又有一定的规律。实际上这张表格是笔者经过了深思熟虑,按照事件的性质将它们重新分组后得来的结果,按照笔者的想法,这15个事件可以分为以下三类。
1.程序加载事件
包括deviceready、pause和resume 3个事件,用于对程序的加载完毕(即生命周期的开始)、暂停和恢复进行处理。
2.被动消息事件
用于对程序运行期间设备发生的一些变化进行处理,如电池电量的变化、网络断开等。包括以下5个事件:online、offline、batterycritical、batterylow、batterystatus。由于这些事件不是用户本人可以控制的,如电池的电量不可能由于用户的意愿而突然增加。因此笔者称其为被动消息事件。
3.主动消息事件
包括backbutton、menubutton、startcallbutton、endcallbutton、volumedownbutton、volumeupbutton和searchbutton这7个事件,分别在用户按下相应的按钮时进行响应。
需要注意的是,并不是每部设备都具备这些按钮,比如在诺基亚最新发布的Nokia X手机中就只有正面的返回按钮以及侧面的音量键。因此如果想在这样的设备中对“搜索”按钮的操作进行处理是不可能的。而即使是在目前主流的安卓手机中一般也省略掉了“搜索键”而仅保留“返回”“菜单”以及在Cordova中没有提到的Home按钮,如图4-6中所示。
图4-6 三按钮布局已成为当前安卓手机的主流设计