Android程序结构解析


Android程序结构解析
2010年06月07日
  Android 程序结构解析通常由以下四个组件来构建一个完整的Android应用程序:
  ● 活动
  ●意图接收器
  ●服务
  ●内容提供者
  然而,并不是所有的Android应用程序都必须具备上面的四个组件,可以由上面的一个或几个来组建。当决定使用以上哪些组件来构Android应用程序时,需要将它们注册在AndroidManifest.xml文件中,这是一个XML配置文件,在这个文件中可以声明应用程序组件以及它们的特性和要求,这个配置文件是每个Android应用程序所必需的。
  活动活动是以上四个组件中最常用的一个。每个活动都是Activity的子类,并实现了一些独有的功能,如管理UI显示和UI的反馈事件。一个活动就相当于应用程序的一个用户界面,由事件响应以及视图等组成。
  大多数的应用程序通常包括多个界面。例如:一个文本聊天应用程序,至少应该包含一个联系人列表界面、一个聊天界面、一个设置界面、~个聊天记录查询界面等等。每个界面其实都可看作是一个活动。显示一个新界面就相当于生成一个对应的活动对象。在一些情况下,活动能够返回给它的上级界面一个返回值,例如一个提供给用户选择照片的活动可以返回给它的调用者用户选择了哪个照片文件。
  当一个新的活动出现时,前一个活动被中断并被放入到一个历史堆栈中。用户可以使用返回键使前一个活动重现。当一个活动不再需要时,可以将它们从历史堆栈中移除。默认情况下,Android会为每个应用程序保留从主界面开始的历史堆栈。
  Android通过一个被称作意图的特殊类,来实现界面与界面之间的跳转。一个意图描述了一个应用程序想要做什么。在意图的描述结构中,含有两个重要的数据结构:动作和动作对应的数据。典型的动作类型包括MAIN、VIEW、PICK、EDIT等等,而动作对应的数据则以URI的形式表示。例如:显示一个联系人信息的界面,可以创建一个意图,并将它的动作设置成vIEW,数据设置成表示这个人信息的URI。除此之外,还有一个被称作意图过滤器(Intent Filter)的相关类。当发生一个有效的目的请求时,意图过滤器用来描述一个活动能够处理什么意图。如上例中所描述,想要正常显示一个联系人信息的界面,必须声明一个意图过滤器,它说明当有联系人数据要被在界面上显示时,知道如何处理它们。通常意图过滤器要被注册在AndroidManifest.xml文件中。
  从一个界面跳转到另一个界面是由解析各种意图实现的。例如:一个活动使用startActivity(myIntent)来调用其他活动时,系统会查找所有已经安装的应用程序的意图过滤器,并从中挑选出能够匹配myIntent意图的活动。随后,这个新的活动接收到意I羽(myIntent)的通知并开始运行。当startActivity方法被调用,解析意图的处理过程随之发生,这个机制有以下两个突出的优点:
  (1)  活动可以通过一个以意图形式产生的请求来重用其他组件的功能。
  (2)  活动可以在任何时候被一个具有等价意图过滤器的新活动所替代。
  意图接收器当想要编写代码来对外部事件做一些处理时,可以使用意图接收器。意图接
  器并不显示UI界面,它是通过Notification Manager来通知用户他们感兴趣的事发生了。意图接收器同样可以被注册在AndroidManifest.xml文件中,同时也可在代码中使用Context.registerReceiver0来注册自己的意图接收器。当一个意图接收器被触发时,系统会根据需要来启动应用程序。
  服务服务是具有长生命周期并且没有用户界面的代码。一个媒体播放器从播放列表中挑选歌曲并播放是服务的一个最好的例子。在一个媒体播放器应用程序中可能包含很多的活动,它们实现了用户从播放列表中选择自己喜欢的歌曲,并使用播放器播放等功能。当应用跳转到一个新的界面时,用户仍然希望音乐继续在后台播放,这时音乐播放本身就不应该由活动来处理了。在这种情况下,活动应该使用Context.startService()来启动一个在后台播放音乐的服务,这样即使界面跳转了,音乐也会如用户所愿继续在后台播放。系统会一直保持音乐播放,直到服务停止。注意:可以使用Context.bindService()来连接一个服务(如果服务没有启动则启动它)。当已经连接上了一个服务,就可以使用服务提供的外部接口来和服务通讯。就媒体播放服务的例子来讲,它提供暂停、循环播放等等。
  内容提供者在Android中,每个应用程序都是有自己的User ID及在自己的进程中执行。
  这样做的好处是,可以保护系统及应用程序,避免被其他不正常的应用程序所影
  响。可以把每个进程想像成是一个黑盒子,彼此不会互相影响,连内存的资料都
  无法共享。如果应用程序之间想要共享数据,就需要使用用内容提供者。一个内
  容提供者就是一个类,它实现了一个标准的方法集合。其他的应用程序可以使用
  这些方法来保存和检索此内容提供者处理过的数据。
  Intent的详细解析在一个Android应用中,主要是由四种组件组成的,这四种组件可参考上一节内容。而这四种组件是独立的,它们之间可以互相调用,协调工作,最终组成个真正的Android应用。在这些组件之间的通讯中,主要是由意图协助完成的。意图负责对应用中一次操作的动作、动作对应的数据、附加数据进行描述,Android根据此意图的描述,负责找到相应的组件,将意图传递给它,并完成组件的调。因此,Intent(意图)在这里起着一个媒体中介的作用,专门提供组件之间互相调用的关信息,实现调用者与被调用者之间的交流。
  Intent抽象描述在Android参考文档中,对意图的定义是执行某操作的一个抽象描述。该抽象描述的具体内容如下:
  首先,它是要执行的动作的一个简要描述,如查看、修改等,Android定义了一套标准动作。此外,还可以根据应用的需要,定义自己的动作,并可定义相应的活动来处理自定义的动作。其次,是执行动作要操作的数据,Android采用指向数据的一个URI方式来实现。另外,除了动作和数据这两个重要属性外,还有一些附加属性:
  (1)类别:被执行动作的附加信息。例如LAUNCHER_CATEGORY表示意图的接受者应该在Launcher中作为顶级应用出现;而ALTERNATIVE_CATEGORY表示当前的意图是一系列的可选动作中的一个,这些动作可以在同一个数据上执行。
  (2)数据类型:显式指定意图的数据类型。一般意图的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用指定的类型。
  (3)组件:指定意图的目标组件的类名称。通常Android会根据意图中包含的其它属性的信息,比如动作、数据/数据类型、类别进行查找,最终找到一个与之匹配的目标组件。但是,如果组件这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,意图的其它所有属性都是可选的。
  (4) 附加信息:是其它所有附加信息的集合。使用附加信息可以为组件提供扩展信息,比如,如果要执行“发送电子邮件’’这个动作,可以将电子邮件的标题、正文等保存在附加信息里,传给电子邮件发送组件。
  总之,动作、数据/数据类型、类别和附加信息一起形成了一种语言。这种语言使系统能够理解诸如“查看某联系人的详细信息”之类的短语。随着应用不断的加入到系统中,它们可以添加新的动作、数据/数据类型和类别来扩展这种语言。应用也可以提供自己的活动来处理已经存在的这样的“短语”,从而改变这些“短语”的行为。
  Android如何解析Intent在应用中,可以以两种形式来使用Intent:
  (1)直接意图:指定了组件属性的意图。通过指定具体的组件类,通知应用启动对应的组件。
  (2)间接意图:没有指定组件属性的意图。这些意图需要包含足够的信息,这样系统才能根据这些信息,在所有的可用组件中,确定满足此意图的组件。
  对于直接意图,Android不需要去做解析,因为目标组件已经很明确,Android
  需要解析的是那些间接意图,通过解析,将意图映射给可以处理此意图的活动、
  意图接收器或服务。意图解析机制主要是通过查找已注册在AndroidManifest.xml中的所有意图过滤器及其中定义的意图,最终找到匹配的意图。在这个解析过程中,Android是通过意图的动作、数据类型、类别这三个属性来进行判断的,判断方法如下:
  (1)如果意图指明定了动作,则目标组件的意图过滤器的动作列表中就必须包含有这个动作,否则不能匹配。
  (2)如果意图没有提供数据类型,系统将从数据中得到数据类型。和动作一样,目标组件的数据类型列表中必须包含意图的数据类型,否则不能匹配。
  (3)如果意图中的数据不是content类型的URI,而且意图也没有明确指定它的数据类型,将根据意图中数据的格式(比如http:或者mailto:)进行匹配。同上,意图的格式必须出现在目标组件的格式列表中。
  (4)如果意图指定了一个或多个类别,这些类别必须全部出现在组建的类别列表中。比如意图中包含了两个类别:LAUNCHER_CATEGORY和ALTERNATIVE_ CATEGORY,解析得到的目标组件必须至少包含这两个类别Android 活动的生命周期
  Android平台是个手机作业系统。手机的特性,就是应该能随时在未完成目前动作的时候,暂停正在使用的功能,切换到接电话、接收短信模式,而且在接完电话回到应用程序时,还希望能看到一样的内容口。
  现在用户使用智能手机,大多已习惯使用多工的作业系统(如Windows
  Mobile),可以在用手机听音乐的同时,执行其他多个程序。同时执行多个程序有它的明显好处,但也有它的缺点。每多执行一个应用程序,就会多耗费一些系统内存,而手机里的内存是相当有限的。当同时执行的程序过多,或是关闭的程序没有正确释放掉内存,系统运行时就会觉得越来越慢,甚至不稳定。为了解决这个问题,Android引入了一个新的机制――生命周期。
  Android应用程序的生命周期是由Android框架进行管理,而不是由应用程序直接控制。通常,每一个应用程序入口一般会是一个活动的onCreate方法,都会占据一个进程。当系统内存即将不足的时候,会依照优先级自动进行进程的回收。不管是使用者或开发者,都无法确定应用程序何时会被回收。关于进程的生命周期将在下一节中介绍,本节主要介绍活动的生命周期。
  一个活动类别除了OnCreate方法之外,还预先定义了OnPause(暂停)、OnResume(继续)等的基本方法,当从一个活动切换到另一个活动的时候,原来的
  活动将经过一连串的状态改变。开发者可以在程序中添加一些各状态相对应的流
  程,每次活动状态改变时,就会执行相对应的流程。要让用户有好的使用体验,活动需要在各个周期中负责保管状态、恢复状态、传送资料等工作。
  活动的生命状态Android的虚拟机(VM)是使用堆栈管理。主要有四种状态:
  (1)活动状态
  活动状态是指用户启动应用程序或活动后,活动运行中的状态。在Android
  平台上,同一个时刻只会有一个活动处于活动或运行状态。其他的活动都处于未启动、停止或是暂停的状态。
  (2)暂停状态
  暂停状态是指当活动暂时暗下来,退到背景画面的状态。当警告对话框或电
  话来了时,都会让原来运行的活动退到背景画面。新出现的警告对话框等界面元件盖住了原来的活动画面。活动处在暂停状态时,用户无法与原活动互动。
  (3)停止状态
  停止状态是指有其他活动正在执行,而这个活动已经离开屏幕,不再动作的
  状态。通过按返回键,可以调出所有处于停止状态的应用程序列表。处于停止状态的活动,还可以通过通知来唤醒。
  (4)已回收或未启动状态
  已回收或未启动状态是指活动尚未被启动、已经被手动终止或已经被系统回收的状态。要手动终止活动,可以在程序中调用finish方法。如果是被系统回收,可能是因为内存不足了,所以系统根据内存不足时的回收规则,将处于停止状态的活动所占用的内存回收。
  活动的运作流程由实际运行来看,我们可以归纳出所有Android应用程序都遵循的运作流程:
  (1)一般启动
  启动一个活动的基本流程为onCreatc->onStart->onResume。该流程首先分配资源给这个活动(创建状态),然后将活动的内容显示到屏幕上(启动状态);在一切就绪后,取得屏幕的控制权(恢复状态),用户可以开始使用这个程序。
  (2)调用另一个活动
  调用另一个活动的基本流程为onPause一>onCreate一>onStart一>onResume一>onStop。该流程首先冻结原来的活动,再交出屏幕控制权;直到活动2完成一般启动流程后,活动才会被停止。
  (3)回到原来活动
  回到原来活动的基本流程为onPause一>onRestart一>onStart一>
  onResume一>onStop一>onDestroy。另外按返回键也可以回到原来的活动。
  (4)退出结束
  退出结束的基本流程为onPausc一>onStop一>onDestroy。如果程序中有直接调用finish方法来关闭活动的话,系统会跳过先冻结的阶段,直接暂停,停止,然后销毁。
  (5)回收后再启动
  回收后再启动的基本流程为onCreate->onStart->onResume。如果被回收掉的活动一旦又重新被调用时,会像一般启动一样再次调用活动的onCreate方法。
  当在模拟器上已经执行过多个应用程序,只要按下返回键,就会开启最近一
  次开启过的活动。这时要是按下多次返回键,理论上迟早会返回到某个已经销毁
  的活动。如果应该开启的活动已经被回收了,那么这个活动会再次被创建。再次被创建的活动,跟原来开启过的活动是不一样的。所以如果要让再次被创建的活动跟原来开启过的一样,那么在活动之间切换时,就要保存资料:即在每次活动运行到暂停或停止状态时先保存资料,然后在创建时将资料读出来。

猜你喜欢

转载自wao338xw.iteye.com/blog/1357925