Android 开发者指南--应用清单文件AndroidManifest

应用清单概览:

  每个应用项目必须在项目源设置的根目录中加入AndroidManifest.xml文件(且必须使用此名称)清单文件会向Android构建工具、Android操作系统和Google play描述应用的基本信息。

重点是,清单文件需声明以下内容:

  应用的软件包名称,其通常与代码的命名空间相匹配。构建项目时,Android构建工具会使用此信息来确定代码实体的位置。打包应用时,构建工具会使用Gradle构建文件中的应用ID来替换此值,而此ID则用作系统和Google play上唯一应用标识符。

  应用的组件,包括所有Activity、服务、广播接收器和内容提供程序。每个组件都必须定义基本属性,例如其Kotlin或Java类的名称。清单文件还能声明一些功能,例如其所能处理的设备配置,以及描述组件如何启动的Intent过滤器。

  应用为访问系统或其他应用的受保护部分所需的权限。如果其他应用想要访问此应用的内容,则清单文件还会声明其必须有的权限。

  应用需要的硬件和软件功能,这些功能会影响哪些设备能够从Google Play安装应用。

如果您使用Android Studio构建应用,则系统会为您创建清单文件,并在您构建应用时(尤其是在使用代码模板时)添加大部分清单元素。

文件功能:

  下文介绍如何在清单文件中反映某些最重要的应用特性。

  软件包名称和应用ID

  清单文件的根元素包含应用软件包名称(通常与项目目录结构,即Java命名空间相匹配)的属性。

  例如,下面代码显示包含软件包名称“com.example.myapp"的<manifest>根元素:

  

<?xml version="1.0" endcoding = "utf-8"?>
 <manifest xmlns: android = "http://schemas.android.com/apk/res/android"
    package = "com.example.app"
    android:versionCode = "1"
    android:versionName = "1.0">
    ...
</manifest>

在将应用构建为最终的应用软件包(APK)时,Android会使用package属性完成两件事情:

  1、他会将此名称用作应用所生成R.java类(用于访问应用资源)的命名空间。

  示例:在上方的清单中,您可以在com.example.myapp.R处创建R类。

  2、它会使用此名称解析清单文件中声明的任何相关类名称。

   示例:在上方的清单文件中,系统会将声明为<activity android:name = ".MainActivity">的Active解析为com.example.myapp.MainActivity

因此,清单package属性中的软件包名称始终与项目中保存Activity和其他应用代码的基础软件包名称相匹配。当然,您可以在项目中加入其他子软件包,但此类文件必须使用package属性的命名空间导入R.java类。

 

但请注意,APK编译完成后,package属性还可以表示应用的唯一应用ID。当构建工具根据package名称执行上述任务后,它们会将package值替换为项目build.gradle文件(用于Android Studio项目)中赋予applicationId属性的值。package属性的这一最终值必须是通用唯一值,因为这是能确保在系统和Google Play中识别应用的唯一方式。

 

清单中的package名称与build.gradle文件中applicationId的区别可能会令人感到有点困惑。但若您保持二者一致,便无需担心任何问题。

 

不过,如果您决定让代码的命名空间(以及清单中的package名称)有别于构建文件的applicationId,请务必完全理解设置应用ID的影响。本页将说明如何不依赖构建文件的applicationId,安全调整清单的package名称,以及如何更改不同构建配置的应用ID。

 

应用组件

  对于在应用中创建的每个应用组件,您必须在清单文件中声明相应的XML元素:

  <activity>用于Activity的每个子类。Activity(活动)代表了一个具有用户界面的单一屏幕,如Java的窗口或者帧。Android的活动是ContextThemeWrapper类的子类。

  <service>用于Service的每个子类。服务是后台运行的组件,执行长时间运行且不需要用户交互的任务。即使应用被销毁依然可以工作。服务基本上包含两种状态 Started 和Bound

  <receiver>用于BroadcastReceiver的每个子类。Android广播接收器(Broadcast Receivers):广播接收器BroadcastReceivers用于响应来自其他应用程序或者系统的广播信息。这些信息有时被称为事件或者意图。例如,应用程序可以初始化广播

    来让其他的应用程序知道一些数据已经被下载到设备,并可以为他们所用。这样广播接收器可以定义适当的动作来拦截这些通信。

  <provider>用于ContentProvider每个子类。内容提供者(Content Provider)组件通过请求从一个应用程序向其他的应用程序提供数据。这些请求由类ContentResolver的方法来处理。内容提供者可以使用不同的方式来存储数据。数据可以被放在数据库,

文件,甚至是网络。

  如果您创建此类组件的任何子类,但未在清单文件中对其进行声明,则系统便无法启动该子类。

  必须使用name属性指定子类的名称,且必须使用完整的软件包名称。例如,可对Activity子类进行如下声明:

<maifest ...>
    <application ..>
        <activity android:name="com.example.app.MainActivity"...>
        </activity>
    </application>
</mainfest>

不过,如果name值的第一个字符是句点,则应用的软件包名称(来自<manifest>元素的package属性)将作为此名称的前缀。例如以下Activity名称将解析为“com.example.myapp.MainActivity”:

<manifest package = "com.example.myapp" ...>
    <application ..>
        <activity android:name = ".MainActivity" ...>
            ...
        </activity>
    </application?
<manifest>

如果你拥有位于子软件包(例如com.example.myapp.purchases中)的应用组件,则name值必须添加缺失的子软件包名称(如".purchases.PayActivity")或使用完全限定的软件包名称。

Intent过滤器

  应用的Activity、服务和广播接收器均由Intent激活。Intent是由Intent对象定义的消息,用于描述要执行的操作,其中包括要执行操作的数据、应执行操作的组件类别以及其他相关说明。

  当应用向系统发布Intent后,系统会根据每个应用清单中的Intent过滤器来查找可处理此Intent应用的组件。系统会启动匹配组件的实例,并向该组件传递Intent对象。如果有多个应用可以处理此Intent,则用户可以选择使用哪个应用。

  应用组件可以包含任意数量的过滤器(通过<intent-filter>元素定义),每个过滤器描述该组件的不同功能。

图标和标签

  许多清单元素拥有icon和label属性,二者分别用于向对应应用组件的用户显示小图标和文本标签。

  任何情况下,在父元素中设置的图标和标签都会称为所有子元素的默认icon和label值。例如在<application>元素中设置的图标和标签即为每个应用组件(如所有Activity)的默认图标和标签。

    只要以实现Intent(意图)的选项形式呈现组件,系统便会向用户显示在该组件的<intent-filter>中设置的图标和标签。默认情况下,此图标继承自为父组件(<activity>或<application>元素)声明的任何图标,但如果Intent过滤器提供唯一操作,且您希望

  该操作在选择器对话框中有更好的指示,则您可能需要修改此图标。

权限

  如果访问敏感数据或某些系统功能,则Android应用必须请求相关权限。每个权限均由唯一标签标识。例如,如果应用需要发送短信,则必须在清单中添加以下代码行:

  

<mainfest...>
    <uses-permisson android:name = "android.permission.SEND_SMS">
</manifest>

从Android 6.0(API级别23)开始,用户可以在运行时同意或拒绝某些应用权限。但是,无论您的应用支持哪个Android版本,您都必须使用清单中的<uses-permisson>元素声明所有元素请求。授予应用权限后,该应用便能使用受保护的功能。否则,该应用在尝试

访问这些功能时会失败。

应用也可以使用权限保护自己的组件。它可以使用Android定义的任何权限,或在其他应用程序中声明的权限。应用也可以定义自己的权限。应用可通过<permission>元素来声明新权限。

 

设备兼容性:

  清单文件也可用于声明应用所需的硬件或软件功能,以及应用兼容的设备类型。Google Play商店不允许在未提供应用所需功能和系统版本的设备上安装应用。

<uses-feature>

  <uses-feature>元素允许您声明应用所需要的硬件和软件功能。例如,如果您的应用无法在缺少罗盘传感器的设备上实现基础功能,您可使用以下清单标记罗盘传感器器声明为必须功能:

 

<mainfest...>
    <uses-feature android:name = "android.hardware.sensor.compass" android:required = "true">
</mainfest>

  注意:如果您想在Chromebook上使用自己的应用,则应考虑一些重要的硬件和软件功能限制。如需了解更多信息,请参阅Chromebook的应用清单的兼容性。

<uses-sdk>

  每个后续平台版本都会新增先前版本未提供的API。如要指明与应用兼容的最低版本,您的清单必须包含<uses-sdk>标签及其minSdkVersion属性。

但请注意,<uses-sdk>元素中的这些属性会被build.gradle文件中的相应属性覆盖。因此,如果您使用的是Android Studio,则必须在此处指定minSdkVersion 和targetSdkVersion值:

  

android{
    defaultConfig{
    
           applicationId 'com.example.myapp'
           minSdkVesrsion 15
          targetSdkVersion 28
          ......    
   }
}

文件约定:

  此部分描述普遍适用于清单文件中所有元素和属性的约定和规则。

元素

  只有<manifest>和<application>元素是必须的,二者必须只能出现一次。大多数其他元素可以不出现或多次出现。但是,必须提供某些元素才能在清单中发挥作用。

属性:

  严格来说,所有属性都是可选的。但是必须指定某些属性才能让元素实现其目的。对于真正可选的属性,参考文档会指定默认值。除了根<manifest>的某些属性外,所有属性名称均以android:前缀开头。例如,

      android:alwaysRetainTaskState.由于该前缀是通用的,因此按名称引用属性时,参考文档通常会将其忽略。

多个值:

  如果可以指定多个值,则几乎总是在重复元素,而非列出单个元素内多个值。例如,Intent过滤器可以列出多个操作:

  

<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>

资源值:

 某些属性的值可以显示给用户,例如,Activity的标题或应用图标。这些属性的值可能因为用户的语言或其他设备配置而异(例如根据设备的像素密度提供不同的图标大小) ,因此您应根据资源或主题设置值,而非将其硬件编码到清单文件中。随后,您可以根据不同设备提供的备用资源更改实际值。

  资源将通过以下格式表示为值:

    

"@[package:]type/name"

  如果资源由您的应用提供,则您可以忽略软件包名称(其亦适用于资源库依赖项提供的情况,因为库资源会合并到您的资源中)。当您想要使用Android框架中的资源时,唯一的其他有效包名称时android。

  type是资源类型(例如string或drawable),name是标识特定资源的名称。下面是示例:

  <activity android:icon = "@drawable/smallPic"...>

  如要应用主题中定义的值,第一个字符必须是 ?,而非@:

  

"?[package:]type/name"

字符串值:

  如果属性值为字符串,则你必须使用反斜杠(\\)来转义字符,例如,使用\\n表示换行符或使用\\uxxxx表示Unicode字符。

 

  

  

  

  

 

    

 

posted @ 2022-05-06 14:41  三里路异乡客  阅读(686)  评论(0编辑  收藏  举报