第二章Android应用程序本章学习目标:了解Android基本组件了解Android生命周期掌握Android程序调试2.1基本组件介绍Android应用程序由组件组成,组件是可以被调用的基本功能模块。Android系统利用组件实现程序内部或程序间的模块调用,以解决代码复用的问题,这是Android系统非常重要的特性。在程序设计时,在AndroidManifest.xml中声明可共享的组件,声明后其他应用程序可以直接调用这些共享组件。Android系统有4个重要的组件,分别是Activity、Service、BroadcaseReceiver和ContentProvider。2.1基本组件介绍Activity是Android中最常用的组件,是应用程序的表示层,Activity一般通过View来实现应用程序的用户界面,相当与一个屏幕,用户与程序的交互是通过该类实现的。Android应用程序可以包含一个或多个Activity,一般在程序启动后会呈现一个Activity,用于提示用户程序已经正常启动。Activity在界面上的表现形式一般是全体窗体,也可以是非全屏悬浮窗体或对话框。Service一般用于没有用户界面,但需要长时间在后台运行的应用。实际上,Service是一个具有较长的生命周期但是并没有用户界面的程序。例如在播放MP3音乐时,使用Service播放MP3音乐,可以在关闭播放器界面的情况下长时间播放MP3音乐,并通过对外公开Service的通信接口,控制MP3音乐播放的启动、暂停和停止。2.1基本组件介绍Service一般由Activity启动,但是并不依赖于Activity,即当Activity的生命周期结束时,Service仍然会继续运行,直到自己的生命周期结束为止。Service的启动方式有两种。startService方式启动是当Activity调用startService方法启动Service时,会依次调用onCreate和onStart方法来启动Service,而当调用stopService方法结束Service时,又会调用onDestroy方法结束Service。Service同样可以在自身调用stopSelf或stopService方法来结束Service。bindService方式启动是Activity调用bindService方法启动Service,此时会依次调用onCreate和onBind方法启动Service。而当通过unbindService方法结束Service时,则会依次调用onUnbind和onDestroy方法。2.1基本组件介绍BroadcastReceiver为用户接收广播通知的组件,当系统或某个应用程序发送广播时,可以使用BroadcastReceiver组件来接收广播信息并做相应处理。在信息发送时,需要将信息封装后添加到一个Intent对象中,然后通过调用Content.sendBroadcast()、sendOrderedBroadcast()或sendStickyBroadcast()方法将Intent对象广播出去,然后接收者会检查注册的IntentFilter是否与收到的Intent相同,当相同时便会调用onReceive()方法来接收信息。三个发送方法的不同之处是使用sendBroadcast()或者sendStickyBroadcast()方法发送广播时,所有满足条件的接收者会随时地执行,而使用sendOrderedBroadcast()方法发送的广播接受者会根据IntentFilter中设置的优先级顺序来执行。2.1基本组件介绍BroadcastReceiver的使用过程如下:1、将需要广播的消息封装到Intent中。2、然后通过三种发送方法中的一种将Intent广播出去。3、通过IntentFilter对象来过滤所发送的实体Intent。4、实现一个重写了onReceive方法的BroadcastReceiver。需要注意的是,注册BroadcastReceiver对象的方式有两种,一种是在AndroidManifest.xml中声明,另一种是在Java代码中设置。在AndroidManifest.xml中声明时,将注册的信息包裹在receiver/receiver标签中,并通过intent-filter标签来设置过滤条件;在Java代码中设置时,需要先创建IntentFilter对象,并为IntentFilter对象设置Intent的过滤条件,并通过Content.registerReceiver方法来注册监听,然后通过Content.unregisterReceiver方法来取消监听2.1基本组件介绍ContentProvider是用来实现应用程序之间数据共享的类。当需要进行数据共享时,一般利用ContentProvider为需要共享的数据定义一个URI,然后其他应用程序通过Content获得ContentResolver并将数据的URI传入即可。Android系统已经为一些常用的数据创建了ContentProvider,这些ContentProvider都位于android.provider下,只要有相应的权限,自己开发的应用程序便可以轻松地访问这些数据。对于ContentProvider最重要的就是数据模型(datamodel)和URI,接下来分别对其进行介绍。数据模型就是ContentProvider为所有需要共享的数据创建一个数据表,在表中,每一行表示一条记录,而每一列代表某个数据,并且其中每一条数据记录都包含一个名为“_ID”的字段类标识每条数据。URI就是每个ContentProvider都会对外提供一个公开的URI来标识自己的数据集,当管理多个数据集时,将会为每个数据集分配一个独立的URI,所有的URI都以“content://”开头。需要注意的是,使用ContentProvider访问共享资源时,需要为应用程序添加适当的权限才可以。权限为“uses-permission.android:name=”android.permission.READ_CONTACTS”/”。2.2Activity生命周期Activity生命周期指Activity从启动到销毁的过程,在这个过程中,Activity一般表现为4种状态,分别是活动状态、暂停状态、停止状态和非活动状态。活动状态是指当Activity在用户界面中处于最上层,用户完全看得到,能够与用户进行交互,则这时Activity处于活动状态;暂停状态是指当Activity在界面上被部分遮挡,该Activity不再处于用户界面的最上层,且不能够与用户进行交互,则这个Activity处于暂停状态;停止状态是指Activity在界面上完全不能被用户看到,也就是说这个Activity被其他Activity全部遮挡,则这个Activity处于停止状态;非活动状态是指Activity所处的不在以上三种状态中的另一种状态。2.2Activity生命周期Activity启动后处于活动状态,此时的Activity处于最上层,是与用户正在进行交互的组件,因此Android系统会努力保证处于活动状态Activity的资源需求,资源紧张时可终止其他状态的Activity;如果用户启动了新的Activity,部分遮挡了当前的Activity,或新的Activity是半透明的,则当前的Activity转换为暂停状态,Android系统仅在为处于活动状态的Activity释放资源时才终止处于暂停状态的Activity;如果用户启动新的Activity完全遮挡了当前的Activity,则当前的Activity转变为停止状态,停止状态的Activity将优先被终止;活动状态的Activity被用户关闭后,或暂停状态或停止状态的Activity被系统终止后,Activity便进入了非活动状态。2.2Activity生命周期图2-1Activity状态变换图活动状态停止状态非活动状态暂停状态2.2Activity生命周期为能够更好地理解Activity的生命周期,还需要对Activity栈做一个简要的介绍。Activity栈保存了已经启动且没有终止的所有Activity,并遵循“后进先出”的原则。如图2-2所示,栈顶的Activity处于活动状态,除栈顶以外的其他Activity处于暂停状态或停止状态,而被终止的Activity或已经出栈的Activity的则不在栈内。Activity的状态与其在Activity栈的位置有着密切的关系,不仅如此,Android系统在资源不足时,也是通过Activity栈来选择哪些Activity是可以被终止的。一般来讲,Android系统会优先选终止处于停止状态,且位置靠近栈底的Activity,因为这些Activity启动顺序最靠前,而且在界面上用户是看不到的。2.2Activity生命周期图2-2Activity栈图ActivityActivityActivityActivityActivity......入栈活动状态暂停状态或停止状态出栈Activity非活动状态Activity释放资源终止非活动状态Activity栈2.2Activity生命周期随着用户在界面的操作和Android系统对资源的管理,Android不断变化在Activity栈的位置,其状态也不断在四种状态中转变。为了能够让Android程序了解自身状态的变化,Android系统提供了多个事件回调函数,在事件回调函数中添加相关代码,就可以在Activity状态变化时完成适当的工作。下面的代码给出了Activity的主要事件回调函数。publicclassMyActivityextendsActivity{protectedvoidonCreate(BundlesavedInstanceState);protectedvoidonStart();protectedvoidonRestart();protectedvoidonResume();protectedvoidonPause();protectedvoidonStop();protectedvoidonDestroy();}2.2Activity生命周期表2-1Activity生命周期的事件回调函数表函数是否可终止说明onCreate()否Activity启动后第一个被调用的函数,常用来进行Activity的初始化,例如创建View、绑定数据或恢复信息等。onStart()否当Activity显示在屏幕上时,该函数被调用。onRestart()否当Activity从停止状态进入活动状态前,调用该函数。onResume()否当Activity能够与用户交互,接受用户输入时,该函数被调用。此时的Activity位于Activity栈的栈顶。onPause()是当Activity进入暂停状态时,该函数被调用。一般用来保存持久的数据或释放占用的资源。onStop()是当Activity进入停止状态时,该函数被调用。onDestroy()是在Activity被终止前,即进入非活动状态前,该函数被调用。2.2Activity生命周期除了Activity生命周期的事件回调函数以外,还有onRestoreInstanceState()和onSaveInstanceState()两个函数经常会被使用,用于保存和恢复Activity的状态信息,例如用户在界面中选择的内容或输入的数据等。这两个函数不是生命周期的事件回调函数,不会因为Activity的状态变化而被调用,但在下述情况下会被调用:Android系统因为资源紧张需要终止某个Activity,但这个Activity在未来的某一时刻还会显示在屏幕上。表2-2Activity状态保存/恢复的事件回调函数说明表函数是否可终止说明onSaveInstanceSta