关于android系统对AndroidManifest文件的解析机制

来源:互联网 发布:php数据类型的意思 编辑:程序博客网 时间:2024/06/02 02:27

        最近在学习android的过程中一直在思考一个问题,我们都知道,在android的AndroidManifest.xml 是每个android程序中必须的文件。它位于整个项目的根目录,描述了package中暴露的组件(activities, services, 等等),他们各自的实现类,各种能被处理的数据和启动位置。一个app可以通过intent开启另一个app的Activity组件,一个系统broadcast广播也可以由多个app截获处理(通过其AndroidManifest文件中声明的intent filter)。那么,系统是如何在时间发起之后在系统中搜寻对应的app或者组件,从而正确启动它们呢?

    我试着猜想了两种种可能的方案:

    1.APK安装后都存在一个特定的目录下,所以系统搜索这个目录下的所有apk包,读取其AndroidManifest文件清单内容,逐个解析,只要其AndroidManifest文件清单中的组件符合要求,则执行特定的操作。由于文件缓存机制,所以读取过的内容还存在于内存中,即使后来又装入了新的APK,也不会有太大的影响。 

    2.系统启动时即读取APK目录下的所有app的apk包中的AndroidManifest文件并进行解析,每一个AndroidManifest用一个数据结构存储节点(内部应该是树形结构),所有的AndroidManifest文件解析数据结构节点形成一个链表,当装入新程序时即将新app的AndroidManifest解析后加入链表。当发生特定事件时搜索这个链表中的节点,将符合条件的节点搜索出来,对其所代表的app或组件进行操作。

    显然,第二种方案比第一种方案效率要高。但是当我后来阅读android sdk开发文档时,发现这么一句话,让我顿时茅塞顿开:


    加上自己的Linux内核功底,我立马认识到,真实的机制应该是这样的:系统应该是将各个apk中AndroidManifest文件声明的相似的属性或者action或者组件连接在同一个链表之中,当发生特定事件时搜索特定的链表以对符合条件的组件执行操作。比如如下声明:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"     
            package="com.android.tutor"     
            android:versionCode="1"     
            android:versionName="1.0">        
        <application android:icon="@drawable/icon" android:label="@string/app_name">        
                <activity android:name=".MainActivity" >        
                        <intent-filter>        
                                <action android:name="android.intent.action.MAIN" />        
                                <category android:name="android.intent.category.LAUNCHER" />        
                        </intent-filter>        
                </activity>        
        </application>        
        <uses-sdk android:minSdkVersion="7" />        
</manifest>

    可将MainActivity组件作为此application的默认启动Activity,并且可以在系统启动程序Launcher中显示的application。系统启动时即将所有的AndroidManifest解析完,并将所有具有android.intent.category.LAUNCHER属性的app连接在“the system's application launcher”链表中。供以后的Launcher程序使用。

    当我们分享图片时,系统会自动列出系统中具有分享功能的app,比如微信、微博、QQ等,供我们选择。系统定然不会临时去解析系统中所有app的AndroidManifest文件以确定系统中所有具有分享功能的app。所以定然是已经实现归入了特定的链表。即系统在某个时刻已经解析完所有app的AndroidManifest文件并形成了供查询的数据结构。

    想到这里,我又想到了一个问题,即当我们点击应用程序时,是谁负责打开了应用程序?每个程序都独立运行于一个java虚拟机中,是谁启动了java虚拟机?我们知道android基于Linux内核,Linux Kernel在底层,固然不是由内核直接启动的。我想,应该是framework吧,后来查看了andoroid的框架图后,明白了,应该就是framework:


    如图,application framework启动下层的虚拟机,将所要打开的app参数传递给VM,由VM负责加载应用程序。

    以上都是个人猜测,真正的机制如何,还需要研究android源码。

0 0
原创粉丝点击