ANDROID 多用户

ANDROID 多用户

从 Android L(5.0)开始引入多用户 API。直到目前,基本上都是隐藏 api 或者需要系统签名才能持有”managed_user" 权限。

Android 的这个 “用户” 并不是等同于 linux 下的用户概念。Android 是基于 Linux 的 OS,Linux 下有一套自己的账户管理体系,而 Android 对此有一些封装和改动。同时,Android 也引进了自己的多用户功能。

Android 与 Linux 的用户概念异同

Linux uid

Linux是多用户系统,每个用户都拥有一个uid,这个uid由系统和用户名做映射绑定。同时,为了便于用户管理(譬如管理文档权限),Linux引入了群组的概念,可以将多个用户归于一个群组。每一个群组拥有一个群组id(gid)。

Android uid

以第三方应用为例做说明:

一个应用被安装后, 系统给分配唯一的 "Application ID", 简称"AppId"。同时系统中会有多个用户 (User), 每个用户也有一个唯一的 ID 值, 称为"UserId" 。

Android 这里的 "UserId" 跟 Linux 的 UserId 完全不是同一个东西。UserId 10000 + appId 才等于 Linux 下的 UserId, 即进程所属用户的概念, 在 Android 我们通常记做 "uid*",以下以微信为例作为说明:

// 查看微信进程信息
$ adb shell ps | grep tencent
USER      PID   PPID  VSIZE   RSS    WCHAN                PC  NAME
u0_a110   26250 416   2144140 203204 SyS_epoll_ 00e7b40428 S com.tencent.mm
u0_a110   26338 416   1794628 123868 SyS_epoll_ 00e7b40428 S com.tencent.mm:push

可以看到微信创建了 2 个进程,其第一列 USER 字段均为 u0_a110,这个 u0_a110 就是 uid(有人也说a110是uid)。

这个字段这样拆解成 int 值:

以"_"为界线, 前一部分是UserId, 后一部分是ApplicationId. 转为int值即为:
u0_a110 == 0 * 10000 + (10110) == 10110 == uid;
         (u0)*(十万)   a110
1> u0即表示userId = 0;
2> a110中的"a"永远翻译为10000(一万)
2> "userId * 100000 + appId = uid"是代码中写死的规则, 全系统通用.

uid 就对应 Linux 系统里 "进程所属用户的概念"
在 Android 系统里, 我们可以很容易发现:

  • 同个应用创建的多个进程, 进程 uid 相同.
  • 不同应用创建的进程, 其 uid 一定不同.(除非设置了 shareUid)

可以通过adb shell dumpsys package com.android.systemui | grep "uid"简单的得到安装应用的uid

UserHandle

public final class UserHandle implements Parcelable {
...
    /**
     * Returns the user id for a given uid.
     * @hide
     */
    public static @UserIdInt int getUserId(int uid) {
        if (MU_ENABLED) {
            return uid / PER_USER_RANGE;
        } else {
            return UserHandle.USER_SYSTEM;
        }
    }

    /** @hide */
    public static @UserIdInt int getCallingUserId() {
        return getUserId(Binder.getCallingUid());
    }

    /** @hide */
    public static @AppIdInt int getCallingAppId() {
        return getAppId(Binder.getCallingUid());
    }
...
}

通过源码可以看到,UserHandle包含三种概念:userid、uid、appid
userid:就是有多少个实际的用户,即手机里的主机、访客等多用户。
uid:上文讲过他跟应用进程相关,除了shareduid的应用,每个用户的每个应用的uid不一样的。
appid:跟app相关,包名相同的appid都一样,即使是不同用户。

你可能感兴趣的:(ANDROID 多用户)