Intent 是 Android 組件通信的核心,匹配邏輯隱藏在 PackageManagerService (PMS) 與 IntentResolver 中。本文從顯式/隱式 Intent 區別、IntentFilter 解析存儲、PMS 掃描 APK 建立索引、查詢入口 queryIntentActivities、四輪過濾匹配、buildResolveList 最終裁決五大維度,憑藉源碼還原完整匹配鏈路。
setComponent / setClassName 鎖定目標組件,直接跳轉,無匹配過程。Action、Data、Category,由系統根據 IntentFilter 解析匹配。// PackageManagerService.java 掃描 APK 時
for (PackageParser.Activity a : pkg.activities) {
mActivities.addActivity(a, "activity"); // mActivities: ActivityIntentResolver
}
ActivityIntentResolver 內部維護四張索引表(ArrayMap<String, F[]>):
mActionToFilter:纯 Action 匹配。mTypedActionToFilter:Action + MIME Type。mSchemeToFilter:URI Scheme。mTypeToFilter / mWildTypeToFilter / mBaseTypeToFilter:MIME 精確/通配/基類型。// ApplicationPackageManager → PMS
public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
ComponentName comp = intent.getComponent();
if (comp != null) { // 顯式
return Collections.singletonList(buildResolveInfo(getActivityInfo(comp)));
}
// 隱式
return mActivities.queryIntent(intent, resolvedType, flags, userId);
}
mTypeToFilter.get(resolvedType)。mWildTypeToFilter.get(baseType)(如 image/*)。mBaseTypeToFilter.get(baseType)。mSchemeToFilter.get(scheme)。mActionToFilter.get(action)。每輪獲得的候選 F[] 進入 buildResolveList 進一步校驗 Category、權限、優先級,最終排序輸出。
PackageManagerService
└─ mActivities: ActivityIntentResolver (extends IntentResolver<ActivityIntentInfo, ResolveInfo>)
├─ mActionToFilter, mTypedActionToFilter, mSchemeToFilter, mTypeToFilter...
└─ queryIntent() → 四輪切分 → buildResolveList() → sortResults()
IntentFilter 越精確(Action+Category+Data),匹配越快、越不易誤觸發。CATEGORY_DEFAULT 是隱式啟動 Activity 的隱性要求,必須在 Filter 中聲明。掌握匹配源碼,能從根上解決「為什麼我的 Activity 沒被喚起」「為什麼彈出選擇器」等疑難雜症。