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。

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