在 Android 中如何確定 App(Activity) 的啟動者

  • 2020 年 1 月 23 日
  • 筆記

最近在幫忙定位一個問題,涉及到某個應用自動啟動了,為了確定是誰調用的,使用如下的日誌進行查看(註:為了簡單考慮,下面的啟動者為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