现在的位置: 首页 > 综合 > 正文

AndroidManifest.xml文件解析

2014年01月06日 ⁄ 综合 ⁄ 共 17523字 ⁄ 字号 评论关闭

  AndroidManifest.xml文件解析。

1、重要性

        AndroidManifest.xml是Android应用程序中最重要的文件之一。它是Android程序的全局配置文件,是每个 android程序中必须的文件。它位于我们开发的应用程序的根目录下,描述了package中的全局数据,包括package中暴露的组件 (activities, services, 等等),以及他们各自的实现类,各种能被处理的数据和启动位置等重要信息。 
因此,该文件提供了Android系统所需要的关于该应用程序的必要信息,即在该应用程序的任何代码运行之前系统所必须拥有的信息。一个典型的Android应用程序的结构如下图所示:

2、主要功能

  • 它指定了该应用程序的Java包:该包名作为应用程序的一个独特标识。 
  • 它描述了应用程序组件:该应用程序由哪些activity,service,broadcast receiver和content provider组成。它指定了实现每个组件的类以及公开发布它们的能力(例如,它们能持有哪个Intent信息)。这些声明使Android系统知道这 儿有什么组件以及在什么条件下它们可以被载入。 
  • 它决定那些进程将容纳应用程序组件。 
  • 它声明了本应用程序必须拥有哪些许可,以便访问API的被保护部分,以及与其他应用程序交互。 
  • 它也声明了其他应用程序在和该应用程序交互时需要持有的许可。 
  • 它列出了Instrumentation类,可以在应用程序运行时提供简档和其他信息。这些声明仅当应用程序在开发和测试过程中被提供;它们将在应用程序正式发布之前被移除。 
  • 它声明了该应用程序所需的Android API的最小化水平。 
  • 它列出了该应用程序必须链接的库。
3、主要结构及规则
        下面列表显示了manifest文件的通常的结构以及它可以含有的元素。每个元素,连同它的所有属性,会在各个单独的文档里进行充分的描绘。 

  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <manifest>  //根节点,描述了package中所有的内容   
  3.     <uses-permission /> //请求你的package正常运作所需赋予的安全许可。一个manifest能包含零个或更多此元素   
  4.     <permission />  //声明了安全许可来限制哪些程序能使用你的package中的组件和功能。一个manifest能包含零个或更多此元素   
  5.     <permission-tree />    
  6.     <permission-group />   
  7.     <instrumentation />  //声明了用来测试此package或其他package指令组件的代码。一个manifest能包含零个或更多此元素   
  8.     <uses-sdk />  //指定当前应用程序兼容的最低sdk版本号   
  9.     <application>  //包含package中application级别组件声明的根节点。此元素也可包含 application中全局和默认的属性,如标签,icon,主题,必要的权限,等等。一个manifest能包含零个或一个此元素(不允许多余一个)   
  10.         <activity>  //用来与用户交互的主要工具。当用户打开一个应用程序的初始页面时一个activity,大部分被使用到的其他页面也由不同的activity所实现并声明在另外的activity标记中。   
  11.             <intent-filter>  //声明了指定的一组组件支持的Intent值   
  12.                 <action />   
  13.                 <category />   
  14.                 <data />   
  15.                     <type/>   
  16.                     <schema/>   
  17.                     <authority/>   
  18.                     <path/>   
  19.             </intent-filter>   
  20.             <meta-data />   
  21.         </activity>   
  22.         <activity-alias>   
  23.             <intent-filter> . . . </intent-filter>   
  24.             <meta-data />   
  25.         </activity-alias>   
  26.         <service>  //Service是能在后台运行任意时间的组件   
  27.             <intent-filter> . . . </intent-filter>   
  28.             <meta-data/>   
  29.         </service>   
  30.         <receiver>   //IntentReceiver能使你的application获得数据的改变或者发生的操作,即使它当前不在运行   
  31.             <intent-filter> . . . </intent-filter>   
  32.             <meta-data />   
  33.         </receiver>   
  34.         <provider>  //ContentProvider是用来管理持久化数据并发布给其他应用程序使用的组件   
  35.             <grant-uri-permission />   
  36.             <meta-data />   
  37.         </provider>   
  38.         <uses-library />   
  39.         <uses-configuration />     
  40.     </application>   
  41. </manifest>  

        下面是按照字母顺序排列的所有可以出现在manifest文件里的元素。它们是唯一合法的元素;你不能加入你自己的元素或属性。

  1. <action>   
  2. <activity>   
  3. <activity-alias>   
  4. <application>   
  5. <category>   
  6. <data>   
  7. <grant-uri-permission>   
  8. <instrumentation>   
  9. <intent-filter>   
  10. <manifest>   
  11. <meta-data>   
  12. <permission>   
  13. <permission-group>   
  14. <permission-tree>   
  15. <provider>   
  16. <receiver>   
  17. <service>   
  18. <uses-configuration>   
  19. <uses-library>   
  20. <uses-permission>   
  21. <uses-sdk>  

        说明:AndroidManifest.xml文件的结构、元素,以及元素的属性,可以在Android SDK文档中查看详细说明。而在看这些众多的元素以及元素的属性前,需要先了解一下这些元素在命名、结构等方面的规则: 
       元素:在所有的元素中只有<manifest>和<application>是必需的,且只能出现一次。如果一个元素包含有其他子元素,必须通过子元素的属性来设置其值。处于同一层次的元素,这些元素的说明是没有顺序的。 
      属性:按照常理,所有的属性都是可选的,但是有些属性是必须设置的。那些真正可选的属性,即使不存在,其也有默认的数值项说明。除了根元素<manifest>的属性,所有其他元素属性的名字都是以android:前缀的; 
      定义类名:所有的元素名都对应其在SDK中的类名,如果你自己定义类名,必须包含类的数据包名,如果类与application处于同一数据包中,可以直接简写为“.”; 
       多数值项:如果某个元素有超过一个数值,这个元素必须通过重复的方式来说明其某个属性具有多个数值项,且不能将多个数值项一次性说明在一个属性中; 
       资源项说明:当需要引用某个资源时,其采用如下格式:@[package :]type :name  例如
<activity android:icon=”@drawable/icon ” . . . > 

       字符串值:类似于其他语言,如果字符中包含有字符“\”,则必须使用转义字符“\\”; 

4、详细说明
 
      值得一提一些常用之处: 

       1、几乎所有的AndroidManifest.xml(以及许多其他Android的xml的文件)在第一个元素中包含了命名空间的声明 xmlns:android="http://schemas.android.com/apk/res/android"。这样使得Android中各
种标准属性能在文件中使用,提供了大部分元素中的数据。

        2、大部分manifests包含了单个<application>的元素,它定义了所有的application级别组件和属性,并能在package中使用。 
        3、任何被用户看作顶层应用程序,并能被程序启动器所用的package,需要包含至少一个Activity组件来支持MAIN操作和LAUNCHER种 类。动作android.intent.action.MAIN指示这是应用程序的入口点。类别 android.intent.category.LAUNCHER将此Activity放在启动器窗口中。
在最外层的<manifest>中包含了包名如 package="cn.androidlover.demo" 、软件的版本号 android:versionCode="1" 以及 android:versionName="1.0"的属性,而里面一层的<application>分支中将可能包含Android程序的
四种对象 Activity、Service、Content Provider以及Receiver。我们每添加上面四个类型中的任一种新对象都需要在androidmanifest.xml文件中添加相应节点,否 则运行时将会产生异常。每一个activity必须要一个<activity>标记对应,无论它给外部使用或是只用于自己的package 中。如果一个activity没有对应的标记,你将不能运行它。

       此文件一个重要的地方就是它所包含的intent-filters。这些filters描述了activity启动的位置和时间。每当一个 activity(或者操作系统)要执行一个操作,例如:打开网页或联系簿时,它创建出一个intent的对象。它能承载一些信息描述了你想做什么,你想
处理什么数据,数据的类型,和一些其他信息。Android比较了intent对象中和每个application所暴露的intent-filter中 的信息,来找到最合适的activity来处理调用者所指定的数据和操作。关于intent的更多信息请访问Intent参考页面。
4.1  Manifest属性介绍

  1. <manifest  xmlns:android="http://schemas.android.com/apk/res/android"  
  2.           package="com.woody.test"  
  3.           android:sharedUserId="string"  
  4.           android:sharedUserLabel="string resource"  
  5.           android:versionCode="integer"  
  6.           android:versionName="string"  
  7.           android:installLocation=["auto" | "internalOnly" | "preferExternal"] >  
  8. </manifest>  

A、xmlns:android
       定义android命名空间,一般为http://schemas.android.com/apk/res/android,这样使得Android中各种标准属性能在文件中使用,提供了大部分元素中的数据。
B、package
       指定本应用内java主程序包的包名,它也是一个应用进程的默认名称
C、sharedUserId
       表明数据权限,因为默认情况下,Android给每个APK分配一个唯一的UserID,所以是默认禁止不同APK访问共享数据的。若要共享数据,第一可以采用Share Preference方法,第二种就可以采用sharedUserId了,将不同APK的sharedUserId都设为一样,则这些APK之间就可以互相共享数据了。详见:http://wallage.blog.163.com/blog/static/17389624201011010539408/
D、sharedUserLabel

       一个共享的用户名,它只有在设置了sharedUserId属性的前提下才会有意义
E、versionCode
       是给设备程序识别版本(升级)用的必须是一个interger值代表app更新过多少次,比如第一版一般为1,之后若要更新版本就设置为2,3等等。
F、versionName
       这个名称是给用户看的,你可以将你的APP版本号设置为1.1版,后续更新版本设置为1.2、2.0版本等等。。。
G、installLocation
        安装参数,是Android2.2中的一个新特性,installLocation有三个值可以选择:internalOnly、auto、preferExternal
       选择preferExternal,系统会优先考虑将APK安装到SD卡上(当然最终用户可以选择为内部ROM存储上,如果SD存储已满,也会安装到内部存储上)
       选择auto,系统将会根据存储空间自己去适应
       选择internalOnly是指必须安装到内部才能运行
       (注:需要进行后台类监控的APP最好安装在内部,而一些较大的游戏APP最好安装在SD卡上。现默认为安装在内部,如果把APP安装在SD卡上,首先得设置你的level为8,并且要配置android:installLocation这个参数的属性为preferExternal)

4.2 application属性介绍
       有关AndroidManifest.xml文件的application分支我们有必要了解一些常见的属性,这里可以看到一些我们实用的选项,比如允许 调试android:debuggable、任务关系android:taskAffinity,比如我们常见的方式创建一个新的任务实用标记
FLAG_ACTIVITY_NEW_TASK,为程序制定一个主题,可以使用android:theme指向一个主题文件。平时我们创建的程序使用一些 安全敏感项,会需要请求系统许可权限,这里可以使用android:permission来制定相关的许可,每个程序的service、 activity、content provider、receiver都需要在application的节点内实现。有关完整的属性可以查看:

  1. <application android:allowClearUserData=["true" | "false"]   
  2.              android:allowTaskReparenting=["true" | "false"]   
  3.              android:debuggable=["true" | "false"]   
  4.              android:description="string resource"   
  5.               android:enabled=["true" | "false"]   
  6.              android:hasCode=["true" | "false"]   
  7.              android:icon="drawable resource"   
  8.               android:label="string resource"   
  9.              android:manageSpaceActivity="string"   
  10.               android:name="string"   
  11.               android:permission="string"   
  12.               android:persistent=["true" | "false"]   
  13.               android:process="string"   
  14.               android:taskAffinity="string"   
  15.               android:theme="resource or theme" >   
  16.      . . .   
  17. </application>  

A、android:allowClearUserData('true' or 'false')
        用户是否能选择自行清除数据,默认为true,程序管理器包含一个选择允许用户清除数据。当为true时,用户可自己清理用户数据,反之亦然
B、android:allowTaskReparenting('true' or 'false')
        是否允许activity更换从属的任务,比如从短信息任务切换到浏览器任务
C、android:backupAgent
        这也是Android2.2中的一个新特性,设置该APP的备份,属性值应该是一个完整的类名,如com.project.TestCase,此属性并没有默认值,并且类名必须得指定(就是个备份工具,将数据备份到云端的操作)
D、android:debuggable
        这个从字面上就可以看出是什么作用的,当设置为true时,表明该APP在手机上可以被调试。默认为false,在false的情况下调试该APP,就会报以下错误:
Device XXX requires that applications explicitely declare themselves as debuggable in their manifest.
 Application XXX does not have the attribute 'debuggable' set to TRUE in its manifest and cannot be debugged.
E、android:description/android:label
        此两个属性都是为许可提供的,均为字符串资源,当用户去看许可列表(android:label)或者某个许可的详细信息(android:description)时,这些字符串资源就可以显示给用户。label应当尽量简短,之需要告知用户该许可是在保护什么功能就行。而description可以用于具体描述获取该许可的程序可以做哪些事情,实际上让用户可以知道如果他们同意程序获取该权限的话,该程序可以做什么。我们通常用两句话来描述许可,第一句描述该许可,第二句警告用户如果批准该权限会可能有什么不好的事情发生
F、android:enabled
        Android系统是否能够实例化该应用程序的组件,如果为true,每个组件的enabled属性决定那个组件是否可以被 enabled。如果为false,它覆盖组件指定的值;所有组件都是disabled。
G、android:hasCode('true' or 'false')
        表示此APP是否包含任何的代码,默认为true,若为false,则系统在运行组件时,不会去尝试加载任何的APP代码
一个应用程序自身不会含有任何的代码,除非内置组件类,比如Activity类,此类使用了AliasActivity类,当然这是个罕见的现象
(在Android2.3可以用标准C来开发应用程序,可在androidManifest.xml中将此属性设置为false,因为这个APP本身已经不含有任何的JAVA代码了)
H、android:icon
        这个很简单,就是声明整个APP的图标,图片一般都放在drawable文件夹下
I、android:killAfterRestore
J、android:manageSpaceActivity
K、android:name
        为应用程序所实现的Application子类的全名。当应用程序进程开始时,该类在所有应用程序组件之前被实例化。
若该类(比方androidMain类)是在声明的package下,则可以直接声明android:name="androidMain",但此类是在package下面的子包的话,就必须声明为全路径或android:name="package名称.子包名成.androidMain"
L、android:permission
        设置许可名,这个属性若在<application>上定义的话,是一个给应用程序的所有组件设置许可的便捷方式,当然它是被各组件设置的许可名所覆盖的
M、android:presistent
        该应用程序是否应该在任何时候都保持运行状态,默认为false。因为应用程序通常不应该设置本标识,持续模式仅仅应该设置给某些系统应用程序才是有意义的。
N、android:process
        应用程序运行的进程名,它的默认值为<manifest>元素里设置的包名,当然每个组件都可以通过设置该属性来覆盖默认值。如果你想两个应用程序共用一个进程的话,你可以设置他们的android:process相同,但前提条件是他们共享一个用户ID及被赋予了相同证书的时候
O、android:restoreAnyVersion
        同样也是android2.2的一个新特性,用来表明应用是否准备尝试恢复所有的备份,甚至该备份是比当前设备上更要新的版本,默认是false
P、android:taskAffinity
        拥有相同的affinity的Activity理论上属于相同的Task,应用程序默认的affinity的名字是<manifest>元素中设定的package名
Q、android:theme
        是一个资源的风格,它定义了一个默认的主题风格给所有的activity,当然也可以在自己的theme里面去设置它,有点类似style。
4.3 Activity属性介绍
        另外:Activity的属性常用的可能为android:name和android:label两个,但我们需要了解所有的属性以帮助解决复杂的问题,完整的如下:

  1. android:allowTaskReparenting=["true" | "false"]  
  2. android:alwaysRetainTaskState=["true" | "false"]  
  3. android:clearTaskOnLaunch=["true"" | "false"]  
  4. android:configChanges=[one or more of: "mcc" "mnc" "locale" "touchscreen" "keyboard" "keyboardHidden" "navigation" "orientation" "fontScale"]  
  5. android:enabled=["true" | "false"]  
  6. android:excludeFromRecents=["true" | "false"]  
  7. android:exported=["true" | "false"]  
  8. android:finishOnTaskLaunch=["true" | "false"]  
  9. android:icon="drawable resource"  
  10. android:label="string resource"  
  11. android:launchMode=["multiple" | "singleTop" | "singleTask" | "singleInstance"]  
  12. android:multiprocess=["true" | "false"]  
  13. android:name="string"  
  14. android:noHistory=["true" | "false"]  
  15. android:permission="string"  
  16. android:process="string"  
  17. android:screenOrientation=["unspecified" | "user" | "behind" | "landscape" | "portrait" | "sensor" | "nonsensor"]  
  18. android:stateNotNeeded=["true" | "false"]  
  19. android:taskAffinity="string"  
  20. android:theme="resource or theme"  
  21. android:windowSoftInputMode=[one or more of: "stateUnspecified" "stateUnchanged" "stateHidden" "stateAlwaysHidden" "stateVisible" "stateAlwaysVisible" "adjustUnspecified" "adjustResize" "adjustPan"]  

        (注:有些在application中重复的就不多阐述了)
1、android:alwaysRetainTaskState
        是否保留状态不变, 比如切换回home, 再从新打开,activity处于最后的状态。比如一个浏览器拥有很多状态(当打开了多个TAB的时候),用户并不希望丢失这些状态时,此时可将此属性设置为true
2、android:clearTaskOnLaunch 
        比如 P 是 activity, Q 是被P 触发的 activity, 然后返回Home, 重新启动 P,是否显示 Q
3、android:configChanges
        当配置list发生修改时, 是否调用 onConfigurationChanged() 方法  比如 "locale|navigation|orientation". 
这个我用过,主要用来看手机方向改变的. android手机在旋转后,layout会重新布局, 如何做到呢?
        正常情况下. 如果手机旋转了.当前Activity后杀掉,然后根据方向重新加载这个Activity. 就会从onCreate开始重新加载.
        如果你设置了 这个选项, 当手机旋转后,当前Activity之后调用onConfigurationChanged() 方法. 而不跑onCreate方法等.
4、android:excludeFromRecents
        是否可被显示在最近打开的activity列表里,默认是false
5、android:finishOnTaskLaunch
        当用户重新启动这个任务的时候,是否关闭已打开的activity,默认是false
        如果这个属性和allowTaskReparenting都是true,这个属性就是王牌。Activity的亲和力将被忽略。该Activity已经被摧毁并非re-parented
6、android:launchMode(Activity加载模式)
        在多Activity开发中,有可能是自己应用之间的Activity跳转,或者夹带其他应用的可复用Activity。可能会希望跳转到原来某个Activity实例,而不是产生大量重复的Activity。这需要为Activity配置特定的加载模式,而不是使用默认的加载模式
Activity有四种加载模式:
standard、singleTop、singleTask、singleInstance(其中前两个是一组、后两个是一组),默认为standard 

  • standard:就是intent将发送给新的实例,所以每次跳转都会生成新的activity。
  • singleTop:也是发送新的实例,但不同standard的一点是,在请求的Activity正好位于栈顶时(配置成singleTop的Activity),不会构造新的实例
  • singleTask:和后面的singleInstance都只创建一个实例,当intent到来,需要创建设置为singleTask的Activity的时候,系统会检查栈里面是否已经有该Activity的实例。如果有直接将intent发送给它。
  • singleInstance:

        首先说明一下task这个概念,Task可以认为是一个栈,可放入多个Activity。比如启动一个应用,那么Android就创建了一个Task,然后启动这个应用的入口Activity,那在它的界面上调用其他的Activity也只是在这个task里面。那如果在多个task中共享一个Activity的话怎么办呢。举个例来说,如果开启一个导游服务类的应用程序,里面有个Activity是开启GOOGLE地图的,当按下home键退回到主菜单又启动GOOGLE地图的应用时,显示的就是刚才的地图,实际上是同一个Activity,实际上这就引入了singleInstance。singleInstance模式就是将该Activity单独放入一个栈中,这样这个栈中只有这一个Activity,不同应用的intent都由这个Activity接收和展示,这样就做到了共享。当然前提是这些应用都没有被销毁,所以刚才是按下的HOME键,如果按下了返回键,则无效
7、android:multiprocess
        是否允许多进程,默认是false
        具体可看该篇文章:http://www.bangchui.org/simple/?t3181.html
8、android:noHistory
        当用户从Activity上离开并且它在屏幕上不再可见时,Activity是否从Activity stack中清除并结束。默认是false。Activity不会留下历史痕迹
9、android:screenOrientation
        activity显示的模式

  • 默认为unspecified:由系统自动判断显示方向
  • landscape横屏模式,宽度比高度大
  • portrait竖屏模式, 高度比宽度大
  • user模式,用户当前首选的方向
  • behind模式:和该Activity下面的那个Activity的方向一致(在Activity堆栈中的)
  • sensor模式:有物理的感应器来决定。如果用户旋转设备这屏幕会横竖屏切换
  • nosensor模式:忽略物理感应器,这样就不会随着用户旋转设备而更改了
10、android:stateNotNeeded
        activity被销毁或者成功重启时是否保存状态
11、android:windowSoftInputMode
        activity主窗口与软键盘的交互模式,可以用来避免输入法面板遮挡问题,Android1.5后的一个新特性。
这个属性能影响两件事情:
【A】当有焦点产生时,软键盘是隐藏还是显示
【B】是否减少活动主窗口大小以便腾出空间放软键盘
各值的含义:
【A】stateUnspecified:软键盘的状态并没有指定,系统将选择一个合适的状态或依赖于主题的设置
【B】stateUnchanged:当这个activity出现时,软键盘将一直保持在上一个activity里的状态,无论是隐藏还是显示
【C】stateHidden:用户选择activity时,软键盘总是被隐藏
【D】stateAlwaysHidden:当该Activity主窗口获取焦点时,软键盘也总是被隐藏的
【E】stateVisible:软键盘通常是可见的
【F】stateAlwaysVisible:用户选择activity时,软键盘总是显示的状态
【G】adjustUnspecified:默认设置,通常由系统自行决定是隐藏还是显示
【H】adjustResize:该Activity总是调整屏幕的大小以便留出软键盘的空间
【I】adjustPan:当前窗口的内容将自动移动以便当前焦点从不被键盘覆盖和用户能总是看到输入内容的部分
4.4 Provider属性介绍
        从Provider节点中用到的定义,可以看到包含了权限控制、排序方式完整的如下:

  1. <provider android:authorities="list"   
  2.            android:enabled=["true" | "false"]   
  3.            android:exported=["true" | "false"]   
  4.            android:grantUriPermissions=["true" | "false"]   
  5.            android:icon="drawable resource"   
  6.            android:initOrder="integer"   
  7.            android:label="string resource"   
  8.           android:multiprocess=["true" | "false"]   
  9.           android:name="string"   
  10.            android:permission="string"   
  11.            android:process=
【上篇】
【下篇】

抱歉!评论已关闭.