1、Android 核心分析( 21 ) -Android 应用框架之AndroidApplicationAndroid ApplicationAndroid 提供给开发程序员的概念空间中Application 只是一个松散的表征概念,没有多少实质上的表征。在Android 实际空间中看不到实际意义上的应用程序的概念,即使有一个叫Application 的类,这个也就是个应用程序上下文状态,是一个极度弱化的概念。Application只是一个空间范畴的概念,Application 就是Activity,Service 之类的组件上下文描述。Application 并不是Android 的核心概念,
2、而Activity 才是Android 的核心概念。从Android 的SDK 文档中,我们知道一般情况Android 应用程序是由以下四种组件构造而成的:Activity,Broadcast Intent Receiver,服务(Service),内容提供器(Content Provider)。我们可以使用下面的图来表示一下Android 的概念空间。这些组件依附于应用程序中,应用程序并不会一开始就建立起来,而是在这些组件建立起来后,需要运行时,才开始建立应用程序对象。2.1 应用进程名称为什么要从应用进程名称开始?作为内核研究,我们还是回到问题的最本质处:不管Activity,Servic
3、e 等组件如何设计和运行,它要提供服务,就必须要依附在Linux 的进程上,建立消息循环,组件才能够真正的运作。Activity 实例是如何Hosting 在Linux 进程上的?这个是我们首先想要弄明白的。我们在的项目中看到android:process=“string“这个定义。allowClearUserData=“true“ | “false“android:allowTaskReparenting=“true“ | “false“android:backupAgent=“string“android:label=“string resource“android:manageSpace
4、Activity=“string“android:name=“string“android:permission=“string“android:persistent=“true“ | “false“android:process=“string“android:restoreAnyVersion=“true“ | “false“android:taskAffinity=“string“android:theme=“resource or theme“ . . .在SDK 用已经描述的很清楚到了。android:processThe name of a process where all co
5、mponents of the application should run. Each component canoverride this default by setting its own process attribute.By default, Android creates a process for an application when the first of its components needs torun. All components then run in that process. The name of the default process matches
6、 the packagename set by the element.By setting this attribute to a process name thats shared with another application, you can arrangefor components of both applications to run in the same process but only if the twoapplications also share a user ID and be signed with the same certificate.为什么要提出这么一个
7、定义?android:process 名称。默认状态下,Activity Manager Service 在应用程序的第一个组件需要运行时将会为应用程序建立一个进程,而这个进程的名字就是android:process=”string”所指定,缺省的是应用程序包的名字。该进程一旦建立,后面的该应用的组件都将运行在该进程中,他们绑定的根据就是这个Android:Process 指定的名称,因为在他们都在同一个应用程序包里,也就具有了同样的进程名字,于是他们都托管在了同一进程中。组件将通过ClassLoader 从Package中获取到应用程序的信息。在建立Actvitiy 时, 如果在应用进程端没
8、有应用对象, 系统在该过程中利用makeApplication 建立一个Application 对象,实例化“android.app.Application“,建立一个应用程序上下文完成例如资源,package 等信息管理。2.2 ActivityThread 运行框架在分析中,我们可以看到真正对应应用进程的不是Application 而是ActivityThread。我们从实际的应用堆栈可以看到:NaiveStart.main()ZygoteInit.mainZygoteInit$MethodAndArgsCall.runMethod.Invokemethod.invokeNativeAct
9、ivityThread.main()Looper.loop()每个应用程序都以ActivityThread.main()为入口进入到消息循环处理。对于一个进程来讲,我们需要这个闭合的处理框架。ActivitiyThread 是应用程序概念空间的重要概念,他建立了应用进程运行的框架,并提供了一个IActivityThread 接口作为与Activity Manager Service 的通讯接口.通过该接口AMS可以将Activity 的状态变化传递到客户端的Activity 对象。23 ActivitiyThread 的建立为了叙述的方便我将Actvitiy Manager Service 简
10、写成AMS。在AMS 中关于应用程序的概念是ProcessRecord,请求都是从Activity,Service等开始的,在Activity 需要Resume 时,此时如果与Activity 相关的应用进程没有起来,AM 则启动应用进程。AMS 与应用进程的绑定分为两个部分,第一部分就是AM 建立应用进程,第二部分就是应用进程Attach 到AM,与AM 建立通讯通道。1 ) 创建建立进程: startProcessLocked(processName,Appinfo.uid) 。该函数在StartSecificActivityLocked 等调用。(1)建立ProcessRecord 对象
11、app, 并将该对象添加到mProcessNames 中。应用对象在mProcessNames 中使用应用名字和uid 来标识自己。如果在同一个Package 中的Activity,如果都使用默认设置,那么这些Activity 都会托管在同一个进程中,这是因为他们在带的ApplicationInfo 中的ProcessName 都是一样的。mPidsSelfLocked 数组记录了PID,这个将会在应用进程跑起来后,将自己Attach 到AM 时,根据pid 找到自己的前世:ProcessRecord.2)android.app.ActivityThread 进程启动Android.app.A
12、ctivityThread 进程建立后,将跳入到ActivityThread 的main 函数开始运行,进入消息循环。应用进程使用thread.attach() 发起AMS 的AttachApplicationLocked 调用, 并传递ActvitiyThread 对象和CallingPid 。AttachApplicationLocked 将根据CallingPid 在mPidsSelfLocked 找到对应的ProcessRecord 实例app,将ActvitiyThread 放置app.thread 中。这样应用进程和AMS 建立起来双向连接。AM 可以使用AIDL 接口,通过app.thread 可以访问应用进程的对象。应用程序通过ActivityThread 提供的框架,建立消息循环Looper 和Handler。从前面的相关章节我们知道有Looper 和Handler,整个系统就可以运作了。为了更为系统的了解应用程序的建立时序及其涉及到数据操作,我给出了应用进程的建立过程示意图: