Android系统越来越安全的同时,系统也越来越复杂。5.x以前(包括5.x)应用程序需要的权限,写入AndroidManifest.xml配置文件,即可。从6.0开始出现了运行时权限检查的概念,运行时权限要在代码里面去主动申请。
从此,Android系统的权限分为安装权限(install permission)和运行时权限(runtime permission)。安装权限在AndroidManifest.xml清单文件中进行配置。运行时权限需要在代码里面动态申请。
举个例子:我要做个通讯录/电话本。通讯录需要读取系统的联系人信息,然后进行显示。Android系统要求:读取系统联系人信息,必须要申请READ_CONTACTS权限。在用户授权之后,才可以去读取联系人信息。我们分别看一下5.x以前和6.x以后,是怎样申请权限的?
1. 5.x以前
在5.x(包括5.x)以前,只需要在应用程序的AndroidManifest.xml文件,加入上面这句,就可以了。
用户在安装这个应用程序的时候,会在安装界面上显示,应用程序申请的权限,用户可以进行权限管理,然后开始安装。应用程序在运行的时候,有读取联系人的权限就可以运行成功,否则就会失败,开发者不能在运行阶段去申请权限。
2. 6.x以后
READ_CONTACTS是运行时权限。
这是Google官网,发布Android 6.0的时候,对版本新特性的介绍。
主要从用户和开发者的角度来对运行时权限进行介绍。用户可以在应用程序运行的时候,管理应用权限,对权限进行授权或撤销。用户可以更好的了解和控制权限。同时,为应用开发者精简了安装和自动更新过程。
通过checkSelfPermission()检查权限,通过requestPermissions()请求权限。
首先检查,本应用是否已经获得了读取通讯录的权限。如果没有获得权限,就去主动申请权限。系统会回调onRequestPermissionsResult()方法,来通知应用程序用户是否授权。
本节从系统源码的角度,去看一下下层的设计和实现逻辑。
我们先看看checkSelfPermission()的实现逻辑。
Frameworks/base/core/java/android/app/ContextImpl.java
Frameworks/base/core/java/android/app/ActivityManagerNative.java
Binder IPC,下面会调用到AMS里面去。
Frameworks/base/services/core/java/com/android/server/ActivityManagerService.java
Frameworks/base/core/java/android/app/ActivityManager.java
这里又一次进行Binder通讯,调用到PMS。
Frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
permissionsState里面存储着从packages.xml读取的系统授权信息,通过调用hasPermission()获取uid是否有permName的授权。
授权数据是保存在文件里面/data/system/packages.xml。程序运行过程中存储授权数据的数据结构在下面的类:
frameworks/base/services/core/java/com/android/server/pm/PermissionsState.java
PermissionsState的内部类PermissionState。一个三个变量mFlags暂不清楚有啥作用,mName存储权限的名字,mGranted标示这个权限是否被授权。这里是最小的数据单元。
PermissionData也是PermissionsState的内部类,用来存储所有uid的某一权限的授权数据。这里用到一个数据结构SparseArray,也是用来存储key-value,不过key只能是int或long。这是一个双数组结构,一个数组用来存储key,一个数组用来存储value,通过两个数组的下标进行key-value的对应。
PermissonsState类里面的ArrayMap的数据结构存放着系统所有的权限数据。ArrayMap是一个特殊实现的哈希表,存放的也是key-value。每一个权限,对应一个PermissionData。
总结一下,授权数据存放涉及到的数据结构,就是上面这三个截图。mPermissions是一个特殊的哈希表,里面存放着系统所有的授权数据,每个权限对应一个PermissionData。mUserStates是一个双数组,存放的也是key-value,存放uid和对应的授权数据,uid对应一个PermissionState。PermissionState是一个元数据类,存放一个权限的授权状态。
推荐阅读:苹果x与xr
查看心情排行你看到此篇文章的感受是: