Android系统编程入门系列之清单文件

在上一篇文章中已经提到,Android系统加载应用程序以后,首先会读取该应用程序的AndroidManifest.xml清单文件,以后根据该清单文件加载后边的东西。因此要开发应用程序,天然要先知道清单文件中都记录了什么东西。通常地,在清单文件中声明定义的内容,称为静态注册,相对应地,能够在代码中定义的内容,称为动态注册。android

清单文件的存储位置就是应用程序的根目录,并且文件名也是固定的,必须为AndroidManifest.xml,清单文件中所包含的内容在Android官网应用清单文件中可查。其中的内容主要有如下三部分。app

应用基本信息

package应用包名属性,该属性要保证系统惟一性,也就是说应用程序所运行的Android机器上,不能有相同包名的两个应用程序。若是想把两个相同包名的应用程序安装到同一台Android机器上,那是连安装这一步都没法成功的。
在开发环境AndroidStudio上,建议清单文件中的package属性与主应用module下的build.gradle文件中的applicationId保持一致,固然官网也给出了不一致的修改方案,可是开发过程当中除非有特殊需求,不然不推荐。ide

versionCodeversionName两个属性分别标记了应用的版本信息,其中versionCode能够在Android系统的设置-应用设置-该应用信息中展现,而versionName只能在应用内部显示调用展现。
在开发环境AndroidStudio上,这两个属性能够经过主应用module下的build.gradle文件直接配置。gradle

上边这些做为基本信息,在Android系统加载该应用时首先加载使用。简而言之,package保证了Android系统上运行的软件与软件之间的惟一性,而versionCode保证了Android系统上所运行的同一个软件在不一样版本之间的惟一性。有了这些基础信息,就能够肯定下边要加载的其余内容了。优化

权限声明

应用程序可能须要联网操做,或者访问Android系统上的系统级应用中的内容,好比通信录信息,这些可能涉及到用户隐私的操做和数据,统一概括为应用权限。ui

应用程序所使用到的权限都要在清单文件中以<uses-permisson />标签形式声明,在name属性值中填入相关权限名。这里的权限名不只可使用Android系统已经提供的权限,还可使用当前应用程序的自定义权限和其余应用程序的自定义权限。自定义权限一样是在清单文件这里定义,使用<permission>标签填写相关信息便可。google

值得注意的是,从Android6.0开始,应用程序用到的危险权限不只要在清单文件中声明,并且在涉及该危险权限的代码调用以前也要动态检查申请。可查询Android官网权限列表Protection level: dangerous类型的权限即为危险权限。code

在动态申请权限时,可以使用checkSelfPermission(String permission)检查应用是否得到相关权限,若是用户没有受权,就须要使用requestPermission(@NonNull String[] permissions, int requestCode)申请相关权限,并在Activity中重载onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)以得到用户对权限申请的处理结果。xml

在Android系统检查并授予当前应用相关权限以后,就能够启动当前应用程序了。每一个应用程序对应AndroidSDK中的android.app.Application类,Application的生命周期即从应用程序启动开始,当Android系统由于内存太低或电源优化时,被动杀死应用程序结束,也多是应用程序主动退出结束。继承

设备兼容

Android系统所搭载的硬件设备是千差万别的,并且同一个应用也可能在不一样的AndroidSDK的版本上运行,这也就是常常谈到的碎片化问题。若是能在清单文件中声明当前应用程序须要具有哪些基础硬件,或者能够在哪些AndroidSDK版本上运行,那就能够在不符合要求的Android系统上禁止安装该应用程序。

使用<users-feature />标签能够声明应用程序所须要的一些硬件要求。
使用<users-sdk />标签能够声明应用程序所须要的AndroidSDK版本要求,该标签下主要有、targetSdkVersionmaxSdkVersiontargetSdkVersion三个属性值,分别对应应用程序所运行AndroidSdk的最低版本,最高版本,目标版本。在开发环境AndroidStudio上,minSdkVersiontargetSdkVersion这两个属性能够经过主应用module下的build.gradle文件直接配置。

组件声明

Android系统的实现就是为了更好的和人类交流,交流的途径主要有四种方式,分别是界面操做(以android.app.Activity类为载体),后台服务(以android.app.Service类为载体),广播通知(以android.app.BroadcastReceiver类为载体),数据交换(以android.app.ContentProvider类为载体),将这四种交流方式所依赖的载体统一称为应用组件,应用组件是依赖于当前应用Application的,因此组件的生命周期只能小于等于当前应用生命周期。

Application对应于清单文件中的<application></application>标签。该标签下有icon属性加载资源文件下的图标,做为应用程序在Android系统的显示图标;label属性则是加载资源文件下的字符串,做为应用程序在Android系统中显示的应用名;name属性做为可填项,可使用继承自android.app.Application的自定义类,若是不填该属性值,则默认为android.app.Application。另外还有其余几个属性值均可以在Android官网清单文件-application标签中查询,经过这些属性值配置,能够更方便的指导Android系统管理当前应用程序。

在当前应用肯定之后,就须要分别加载该应用下的组件信息了,应用程序只有一个,可是组件能够有多个,只要名称不冲突便可,因此组件的声明是嵌套在<application></application>标签内部的,下面是每种组件在AndroidManifest.xml中对应的标签名。

组件名 Activity Service BroadcastReceiver ContentProvider
清单文件标签名 activity service receiver provider

组件标签内必需要有name属性,以指向代码中自定义的组件类,值得注意的是,一个应用程序中,能够有多个界面,多个服务,多个广播接收器,多个数据提供者,因此name属性就是为了区分多个相同种类组件的。

provider标签中还必需要有authorities属性值,这是因为ContentProvider是对其余应用提供数据,这就好像该应用将数据保存到一个保险箱中提供给其余应用,而其余应用必须有该保险箱的密码才能打开保险箱以访问该应用的数据,而authorities正是起到这个密码的相似效果。

activity标签,service标签,provider标签,还能够内嵌<intent-filter><\intent-filter>标签做为组件内信息,使用意图过滤标记的组件,能够在代码中快速响应该意图,执行响应后逻辑。

启动应用程序后,必需要加载一个Activity界面,而加载哪个呢?这也就用到<intent-filter><\intent-filter>标签了,只有在该标签内嵌套了<action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" />两个固定标签内容的<activity><\activity>,才容许做为第一个界面加载。因此很天然的想到,一个<application><\application>标签内只容许有一个<activity><\activity>能够嵌套上面的意图过滤器内容。


至此,Android系统对应用程序的清单文件基本解析以后,就获取了该应用的全部静态信息,当应用安装以后,就能够在桌面Launcher应用程序中显示该应用,等待用户点击启动该应用了。

相关文章
相关标签/搜索