每个应用必须有一个AndroidManifest.xnl文件(就是这个名字)在它的根目录。清单文件给安卓系统呈现关于我们的app的基本信息,在系统运行任何程序代码之前必须有的信息(为什么这么设计?)。除了其他事情,清单做下面的:
Structure of the Manifest File
下面的表格展示了清单文件的通常结构合他能包含的每一个元素。每一个元素,连同他的所有属性,被在独立的文件中记录。
<?xml version="1.0" encoding="utf-8"?>
<manifest>
<uses-permission/>
<permission/>
<permission-tree/>
<permission-group/>
<instrumentation/>
<uses-sdk/>
<uses-configuration/>
<uses-feature/>
<supports-screens/>
<compatible-screens/>
<supports-gl-texture/>
<application>
<activity>
<intent-filter>
<action/>
<category/>
<data/>
</intent-filter>
<meta-data/>
</activity>
<activity-alias>
<intent-filter>. . . </intent-filter>
<meta-data/>
</activity-alias>
<service>
<intent-filter>. . . </intent-filter>
<meta-data/>
</service>
<receiver>
<intent-filter>. . . </intent-filter>
<meta-data/>
</receiver>
<provider>
<grant-uri-permission/>
<meta-data/>
<path-permission/>
</provider>
<uses-library/>
</application>
</manifest>
File Conventions
一些惯例和规则通常应用于清单中所有的元素和属性:
Elements
只有<manifest>和<application>元素必须有,他们必须必展示同时只能出现一次。大多数的其他元素能出现很多次或不出现,虽然至少有一些必须展示给清单文件去实现有意义的事。
如果一个元素包含任何东西,它包含其他元素。所有的值通过属性设置,不是作为字符数据在一个元素中。
同一级别的元素通常不排序。举例,<activiy>,<provider>,<service>元素可以任何顺序混杂。(一个<activity-alias>元素是这个规则的例外:他必须跟随他别名的<activity>).
Attributes
在正式的观念,所有的属性是可选的。然而,有些必须为一个元素指定去完成它的目标。
除了根<manifest>元素中的一些属性,所有的属性命名以“android:”前缀开头。举例,android:alwaysRetainTaskState.因为这个前缀是通用的,这个文档通常省略它当通过名字指向一个属性。
Declaring class names
许多元素对应Java对象,包括包括应用本身的元素(<application>),和它的基本组件,活动(<activity>),服务(<service>),广播接收器(<receiver>),和内容提供器(<provider>)。
如果我们定义一个子类,正如我们几乎总是为组件类(Activity,Service,BroadcastReceiver,and ContentProvider),子类通过一个name属性声明。name必须包含一个全包名(为什么会出现.class,因为只有一个包吗?)。比如,一个服务是子类可能像下面声明:
<manifest . . . > <application . . . > <service android:name="com.example.project.SecretService" . . . > . . . </service> . . . </application> </manifest>
然而,作为速记,如果字符串的第一个字符是一个“.”,这个字符附件到包名(由<manifest>的package属性指定)后,下面的任何和上面的一样:
<manifest package="com.example.project" . .. >
<application . . . >
<service android:name=".SecretService". . . >
. . .
</service>
. . .
</application>
</manifest>
当启动一个组件,安卓创建一个命名的子类的实例,如果子类没有指定,它创建一个基础类。(name属性没有指定 ,那么就创建父类?)
Multiple values
如果可以指定不只一个值,元素几乎总是重复,而不是在一个元素列出多个。下面是一个有多个actions intent filter:
<intent-filter . . . >
<action android:name="android.intent.action.EDIT" />
<action android:name="android.intent.action.INSERT" />
<action android:name="android.intent.action.DELETE" />
. . .
</intent-filter>
Resource values
有些属性有可以展示给用户的值,举例,一个活动有一个label和icon。这些属性的值应该局部化,因此从一个资源或主题设置。资源值以下面的格式表示:
@[package:]type:name
包名可以省略如果资源和应用在同一个包(这是什么意思,多数都省略了啊),type是资源的类型,比如“string”和“drawable”,name是标识特定资源的。举例:
<activity android:icon="@drawable/smallPic". . . >
来自Theme的值以类似的习惯表达,但是以“?”开头,而不是“@”。
?[package:]type:name
String values
当一个属性的值是string,双反斜杠必须使用来转义字符。比如:
Where an attributevalue is a string, double backslashes ('\\') must be used to escape characters— for example, '\\n' for a newline or '\\uxxxx' for a Unicode character.
下面的部分描述一些安卓特性如何在清单文件中反射。
一个应用的核心组件(its activities, services, and broadcast receivers)由intents激活。一个Intent是一捆信息(一个Intent对象)描述一个要求的action,包括要行动的data,应该执行这个action的组件的category和其他相关的指示。安卓查找一个合适的组件响应这个intent,启动组件的一个新实例如果需要,同时传递给它这个Intent对象。
Components advertise theircapabilities组件声称他们的能力—他们可以响应的intent类型,通过intent filters。因为安卓系统必须学习哪个intent一个组件可以处理在启动这个组件之前,intent filters在清单文件以<intent-filter>元素指定。一个组件可以有任何数量filters,每一个描述不同的capability。
一个intent,明确命名一个目标组件,会激活那个组件,filter不起作用。但是一个intent不通过名字指定一个目标,可以激活一个组件只有在他通过组件的一个filters。
一些元素必须有icon和label属性给一个小icon和一个text label可以展示给用户。一些也有一个描述属性对于更长的说明text,也可以展示在屏幕上。举例,<permission>元素有所有这三个属性,所以当用户被询问是否授予权限给一个权限给要求它的应用,一个icon表示这个权限,权限的name,和一个需求的描述可以全部展示给用户。
在每种情况下,icon和lable设置进一个包含元素成为默认的icon和label设置给所有容器 中的子元素。因此,设置在<application>元素中icon和label是每一个应用组件的默认icon和label。类似的,icon和label设置为一个组件的,举例,一个<activity>元素,是这个组件的每一个<intent-filter>元素的默认设置。如果一个<application>元素设置一个label,但是一个活动和他的intent filter没有,应用的label被处理为活动和intent filter的label。
为一个intent filter设置的icon和label被用来展示一个组件,每当这个组件展示给用户作为令人满意的功能实现。举例,一个filter有“android.intent.action.MAIN”和“android.intent.category.LAUNCHER”设置建议一个活动作为初始一个应用,就是,作为一个应该在应用启动。Icon和label设置在filter中的,因此是在launcher中展示的。
The icon and label set for an intent filter are used torepresent a component whenever the component is presented to the user asfulfilling the function advertised by the filter. For example, a filter with"android.intent.action.MAIN
" and "android.intent.category.LAUNCHER
"settings advertises an activity as one that initiates an application — that is,as one that should be displayed in the application launcher. The icon and labelset in the filter are therefore the ones displayed in the launcher.
一个权限是对设置上的部分代码和数据的一个限制访问。这个限制被用来保护关键数据和代码,这些可能被滥用扭曲或者破坏用户体验。
每一个权限通过一个唯一的label标识。通常label暗示他显示的动作。下面的一些安卓定义的权限:
android.permission.CALL_EMERGENCY_NUMBERS
android.permission.READ_OWNER_DATA
android.permission.SET_WALLPAPER
android.permission.DEVICE_POWER
一个功能最多只能保护一个许可。
如果一个应用需要访问权限保护的功能,他必须在清单文件使用一个<uses-permission>元素声明他需要那个权限,然后,当应用被安装到这个设备上,安装器决定是否授予这个请求权限通过检查标记在应用证书的权限,在某些情况下,询问用户。如果权限被授予,应用能够使用包含的功能。如果没有,尝试访问这些feature会简单失败没有任何通知给用户。
一个应用也可以包含他自己的组件(activities,services, broadcast receivers, and content providers)使用权限。他可以使用安卓定义的任何权限(listed in android.Manifest.permission
)或者由其他应用声明的。或者它可以定义自己的。一个新权限使用<permission>声明。举例,一个活动可以像下面一样保护:
注意到,在这个例子中,DEBIT_ACCT权限不仅仅使用<permisson>元素声明,他们的使用也要求<uses-permission>元素。他的使用必须必须被请求为了让应用其他组件启动这个保护的活动,即使这个保护是程序自己的。
Note that, in this example, the DEBIT_ACCT
permission is not only declared with the <permission>
element, its use is also requested with the <uses-permission>
element. Its use must be requested in order for other components of theapplication to launch the protected activity, even though the protection isimposed by the application itself.
如果,在同一个例子,权限属性被设置为其他权限(比如android.permission.CALL_EMERGENCY_NUMBERS),
没有必要使用<permission>元素再次声明。然而,它仍然是必须的使用<uses-permission>请求他的使用。
这个<permission-tree>元素为一组权限声明一个命名空间,权限会被定义在code中。
The <permission-tree>
element declares a namespace for a group of permissions that will be defined incode. And <permission-group>
defines a label for a set of permissions (both those declared in the manifestwith <permission>
elements and those declared elsewhere). It affects only how the permissions aregrouped when presented to the user. The <permission-group>
element does not specify which permissions belong to the group; it just givesthe group a name. A permission is placed in the group by assigning the groupname to the <permission>
element's permissionGroup
attribute.
每一个应用都被默认的安卓library连接,包含构建应用的基本包(有基本类,比如android.permission.CALL_EMERGENCY_NUMBERS
等等
)。
然而,一些包属于他们自己的library。如果我们的应用使用这些包的代码,必须明确的请求连接他们。清单文件必须包含一个独立的<used-library>同元素来命名每一个library。(library name可以在文档中找到)
这个和jar包有什么区别,build中compile的