Android下uid与多用户释疑(二)

3.Android多用户
Android4.2开始支持多用户。Linux的uid/gid多用户体系已经被用在App管理上了,所以android重新开发了一套多用户体系,在UserManagerService中管理,PackageManagerService和ActivityManagerService中也有相关逻辑。Android的多用户可以做到不同用户的应用的物理文件级(数据)的区分,以实现不同用户有不同的壁纸、密码,以及不同的应用等。本文不展开多用户的机制,只集中于uid。
先看一下在多用户下,应用的uid怎么变化。
在一个有两个用户(用户id分别为0和10)的安卓设备上,在用户10下安装一个应用,此时,在0下是看不到这个应用的。
从packages.xml查看此应用的uid:userId=”10078”
Process.myUid()得到uid为”1010078”
Process.myUserHandle()得到”userHandle{10}”
在另一个用户0下安装此应用。
查看packages.xml,看到uid没有变化10078
Process.myUid()得到uid为”10078”
Process.myUserHandle()得到”userHandle{0}”
adb shell进入命令行,分别查看data/user/0和data/user/10下面此应用的数据区:
用户0:
这里写图片描述
用户10:
这里写图片描述
可以看到,实际上应用在内部虽然有多用户,但只有一个uid,在不同的用户下,通过uid和用户id合成一个新的uid,以保证在每个用户下能够区分。
android.os.UserHandle这个类对外提供有关多用户的接口。
从里面的一些api代码可以看到uid在多用户下的处理逻辑:
多用户支持开关:
这里写图片描述
注意一个api getUid()。这就清楚了,将用户id 10作为第一个参数,packages.xml中记录的该应用的uid 10078作为第二个参数传入,得到了这个应用在10用户下的uid——1010078!
这里写图片描述
这里写图片描述
通过应用的uid得到当前用户的userId,以上过程的逆过程:
这里写图片描述
从另一个核心的api myUserId()更能清楚地看到应用uid和用户id的关系:
这里写图片描述
当一个应用使用UserHandle.myUserId()来获取当前的用户id的时候,其实就是从他自己的进程得到应用的uid,然后通过上述逻辑计算出当前的用户id。
从Process.myUserHandle()也能清楚地看到这个逻辑:
这里写图片描述
从概念和API命名上,确实有些混乱,但Android也情非得已,Process的API Level是1,UserHandle的API Level是17,可见在最初的android上面,已经将Linux uid/gid给了应用id了,当时应该也没有考虑android有一天需要支持多用户。直到4.2(API Level 17),引入了多用户时,已经是若干年过去了,Process已经被无数的开发者使用,无法改变。只能接受这个概念上混淆了。
可以用如下的几点来简单地澄清这些id概念:
(1)Process中的xxid相关的概念和API是关于应用id的。
(2)UserHandle中的xxid相关的概念和API是关于Android用户id的。
(3)Process有接口得到UserHandle实例。
注:以上源代码Android版本为4.4.4。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章