10

在 Android 中如何确定 App(Activity) 的启动者 - 技术小黑屋

 4 years ago
source link: https://droidyue.com/blog/2019/12/01/android-uid-process-name/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在 Android 中如何确定 App(Activity) 的启动者

Dec 1st, 2019

最近在帮忙定位一个问题,涉及到某个应用自动启动了,为了确定是谁调用的,使用如下的日志进行查看(注:为了简单考虑,下面的启动者为launcher)

1
2
3
4
(pre_release|✔) % adb logcat | grep -E "ActivityManager: START" --color=always
I ActivityManager: START u0 {act=android.intent.action.MAIN
cat=[android.intent.category.HOME] flg=0x10000000 hwFlg=0x10
cmp=com.huawei.android.launcher/.unihome.UniHomeLauncher (has extras)} from uid 10070

我们看最后看到这个from uid 10070,嗯,基本定位到了是这个uid的应用启动了。

确定 uid 10070 是哪个 App

确定uid不能说明问题,我们至少需要确定是哪个应用,我们尝试使用下面的命令过滤进程有关数据

1
2
adb shell ps | grep 10070
没有任何数据输出

然而一无所获。

当然前面说了,示例的启动者是launcher,那我们过滤一下launcher

1
2
adb shell ps | grep launcher
u0_a70        2207   620 4979992 156312 0                   0 S com.huawei.android.launcher

我们发现了u0_a7010070貌似有一些关联(至少都含有70)

于是我们使用下面的命令确定id

1
2
adb shell id u0_a70
uid=10070(u0_a70) gid=10070(u0_a70) groups=10070(u0_a70), context=u:r:shell:s0

果然,u0_a7010070 是有关联的

u0_a70 的含义

  • u0 默认的手机第一个用户(可以通过设置里面的多用户新增和切换)
  • a 代表app
  • 70 代表着第70个应用

简单而言,对应的公式是这样

u0_a70 = “u0_” + “a” + (uid(这里是10070) – FIRST_APPLICATION_UID(固定值10000))

具体复杂的转换,请参考这段代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
     * Generate a text representation of the uid, breaking out its individual
     * components -- user, app, isolated, etc.
     * @hide
     */
    public static void formatUid(StringBuilder sb, int uid) {
        if (uid < Process.FIRST_APPLICATION_UID) {
            sb.append(uid);
        } else {
            sb.append('u');
            sb.append(getUserId(uid));
            final int appId = getAppId(uid);
            if (isIsolated(appId)) {
                if (appId > Process.FIRST_ISOLATED_UID) {
                    sb.append('i');
                    sb.append(appId - Process.FIRST_ISOLATED_UID);
                } else {
                    sb.append("ai");
                    sb.append(appId - Process.FIRST_APP_ZYGOTE_ISOLATED_UID);
                }
            } else if (appId >= Process.FIRST_APPLICATION_UID) {
                sb.append('a');
                sb.append(appId - Process.FIRST_APPLICATION_UID);
            } else {
                sb.append('s');
                sb.append(appId);
            }
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   /**
     * Defines the start of a range of UIDs (and GIDs), going from this
     * number to {@link #LAST_APPLICATION_UID} that are reserved for assigning
     * to applications.
     */
    public static final int FIRST_APPLICATION_UID = 10000;
    /**
     * Last of application-specific UIDs starting at
     * {@link #FIRST_APPLICATION_UID}.
     */
    public static final int LAST_APPLICATION_UID = 19999;
    /**
     * First uid used for fully isolated sandboxed processes (with no permissions of their own)
     * @hide
     */
    @UnsupportedAppUsage
    @TestApi
    public static final int FIRST_ISOLATED_UID = 99000;
     /**
     * First uid used for fully isolated sandboxed processes spawned from an app zygote
     * @hide
     */
    @TestApi
    public static final int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000;

References

Posted by androidyue Dec 1st, 2019Android, Linux

« 这可能是最好的 Android/Kotlin日志输出方法 Mac 下在终端直接查看图片 »


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK