Android中级——PackageManagerService和Intent

news/2025/2/14 5:38:02/

PackageManagerService和Intent

  • PackageManagerService
  • Intent

PackageManagerService

PMS扫描已安装的apk,解析其AndroidManifest.xml获取App相关信息,如下是其构造函数的相关片段

......
if (partition.getPrivAppFolder() != null) {		//扫描系统应用,路径/system/priv-appscanDirTracedLI(partition.getPrivAppFolder(), systemParseFlags,systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0,packageParser, executorService);
}......//扫描系统应用,路径/system/app
scanDirTracedLI(partition.getAppFolder(), systemParseFlags,systemScanFlags | partition.scanFlag, 0,packageParser, executorService);......
if (!mOnlyCore) {		//扫描非系统应用,路径/data/data/app......scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,packageParser, executorService);
}......

调用scanDirTracedLI()、scanDirLI()

private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime,PackageParser2 packageParser, ExecutorService executorService) {final File[] files = scanDir.listFiles();......ParallelPackageParser parallelPackageParser =new ParallelPackageParser(packageParser, executorService);int fileCount = 0;for (File file : files) {		//判断是否是apk文件final boolean isPackage = (isApkFile(file) || file.isDirectory())&& !PackageInstallerService.isStageName(file.getName());if (!isPackage) {continue;}parallelPackageParser.submit(file, parseFlags);fileCount++;}......
}
  • 调用ParallelPackageParser的submit()并行解析
  • 调用PackageParser2的parsePackage()
  • 调用ParsingPackageUtils的parsePackage()、parseMonolithicPackage()、parseBaseApk()、parseBaseApkTags()

parseBaseApkTags()开始解析AndroidManifest

private ParseResult<ParsingPackage> parseBaseApkTags(ParseInput input, ParsingPackage pkg, TypedArray sa, Resources res, XmlResourceParser parser, int flags) throws XmlPullParserException, IOException {ParseResult<ParsingPackage> sharedUserResult = parseSharedUser(input, pkg, sa);......boolean foundApp = false;final int depth = parser.getDepth();int type;while ((type = parser.next()) != XmlPullParser.END_DOCUMENT&& (type != XmlPullParser.END_TAG|| parser.getDepth() > depth)) {if (type != XmlPullParser.START_TAG) {continue;}String tagName = parser.getName();		//获取标签final ParseResult result;if (PackageParser.TAG_APPLICATION.equals(tagName)) {if (foundApp) {if (PackageParser.RIGID_PARSER) {result = input.error("<manifest> has more than one <application>");} else {Slog.w(TAG, "<manifest> has more than one <application>");result = input.success(null);}} else {		// 解析Application标签foundApp = true;result = parseBaseApplication(input, pkg, res, parser, flags);}} else {		//解析其他全局标签(如permission)result = parseBaseApkTag(tagName, input, pkg, res, parser, flags);}if (result.isError()) {return input.error(result);}}......return input.success(pkg);
}

parseBaseApplication()开始解析Application

private ParseResult<ParsingPackage> parseBaseApplication(ParseInput input, ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags) throws XmlPullParserException, IOException {final String pkgName = pkg.getPackageName();int targetSdk = pkg.getTargetSdkVersion();TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestApplication);try {......String name = sa.getNonConfigurationString(R.styleable.AndroidManifestApplication_name, 0);if (name != null) {		// 解析name属性String packageName = pkg.getPackageName();String outInfoName = ParsingUtils.buildClassName(packageName, name);......pkg.setClassName(outInfoName);}TypedValue labelValue = sa.peekValue(R.styleable.AndroidManifestApplication_label);if (labelValue != null) {	// 解析label属性pkg.setLabelRes(labelValue.resourceId);if (labelValue.resourceId == 0) {pkg.setNonLocalizedLabel(labelValue.coerceToString());}}.......if (pkg.isAllowBackup()) {	// 解析isAllowBackup属性......}......CharSequence pname;		// 解析process属性if (targetSdk >= Build.VERSION_CODES.FROYO) {pname = sa.getNonConfigurationString(R.styleable.AndroidManifestApplication_process,Configuration.NATIVE_CONFIG_VERSION);} else {  pname = sa.getNonResourceString(R.styleable.AndroidManifestApplication_process);}ParseResult<String> processNameResult = ComponentParseUtils.buildProcessName(pkgName, null, pname, flags, mSeparateProcesses, input);......String processName = processNameResult.getResult();pkg.setProcessName(processName);......} finally {sa.recycle();}......while ((type = parser.next()) != XmlPullParser.END_DOCUMENT&& (type != XmlPullParser.END_TAG|| parser.getDepth() > depth)) {if (type != XmlPullParser.START_TAG) {continue;}final ParseResult result;String tagName = parser.getName();boolean isActivity = false;switch (tagName) {case "activity":		// 解析ActivityisActivity = true;// fall-throughcase "receiver":	// 解析receiverParseResult<ParsedActivity> activityResult =ParsedActivityUtils.parseActivityOrReceiver(mSeparateProcesses, pkg,res, parser, flags, PackageParser.sUseRoundIcon, input);if (activityResult.isSuccess()) {ParsedActivity activity = activityResult.getResult();if (isActivity) {hasActivityOrder |= (activity.getOrder() != 0);pkg.addActivity(activity);} else {hasReceiverOrder |= (activity.getOrder() != 0);pkg.addReceiver(activity);}}result = activityResult;break;case "service":	// 解析serviceParseResult<ParsedService> serviceResult =ParsedServiceUtils.parseService(mSeparateProcesses, pkg, res, parser,flags, PackageParser.sUseRoundIcon, input);if (serviceResult.isSuccess()) {ParsedService service = serviceResult.getResult();hasServiceOrder |= (service.getOrder() != 0);pkg.addService(service);}result = serviceResult;break;case "provider":		// 解析providerParseResult<ParsedProvider> providerResult =ParsedProviderUtils.parseProvider(mSeparateProcesses, pkg, res, parser,flags, PackageParser.sUseRoundIcon, input);if (providerResult.isSuccess()) {pkg.addProvider(providerResult.getResult());}result = providerResult;break;......default:result = parseBaseAppChildTag(input, tagName, pkg, res, parser, flags);break;}......}......return input.success(pkg);
}

上面通过PackageManager的submit()并行解析,解析完后封装成ParseResult放到一个队列里,后面再利用scanDirLI()的take()获取解析结果

for (; fileCount > 0; fileCount--) {ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();Throwable throwable = parseResult.throwable;int errorCode = PackageManager.INSTALL_SUCCEEDED;if (throwable == null) {......try {addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,currentTime, null);}......}......}
}

调用addForInitLI(),将ParsedPackage封装成ScanResult,再封装成ReconcileRequest

private AndroidPackage addForInitLI(ParsedPackage parsedPackage, @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime, @Nullable UserHandle user) throws PackageManagerException {......final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags, scanFlags| SCAN_UPDATE_SIGNATURE, currentTime, user, null);if (scanResult.success) {synchronized (mLock) {boolean appIdCreated = false;try {final String pkgName = scanResult.pkgSetting.name;final Map<String, ReconciledPackage> reconcileResult = reconcilePackagesLocked(new ReconcileRequest(Collections.singletonMap(pkgName, scanResult),mSharedLibraries,mPackages,Collections.singletonMap(pkgName, getSettingsVersionForPackage(parsedPackage)),Collections.singletonMap(pkgName,getSharedLibLatestVersionSetting(scanResult))),mSettings.mKeySetManagerService);appIdCreated = optimisticallyRegisterAppId(scanResult);commitReconciledScanResultLocked(reconcileResult.get(pkgName), mUserManager.getUserIds());}......}}......return scanResult.pkgSetting.pkg;
}

调用commitReconciledScanResultLocked()封装成PackageSettings,再调用commitPackageSettings()将将解析到的四大组件(AndroidPackage)存入mComponentResolver

private void commitPackageSettings(AndroidPackage pkg,@Nullable AndroidPackage oldPkg, PackageSetting pkgSetting,final @ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg) {......synchronized (mLock) {......mComponentResolver.addAllComponents(pkg, chatty);......}}......
}

ComponentResolver的addAllComponents()将四大组件分别存入到对应的列表

private final ActivityIntentResolver mActivities = new ActivityIntentResolver();private final ProviderIntentResolver mProviders = new ProviderIntentResolver();private final ActivityIntentResolver mReceivers = new ReceiverIntentResolver();private final ServiceIntentResolver mServices = new ServiceIntentResolver();void addAllComponents(AndroidPackage pkg, boolean chatty) {......synchronized (mLock) {addActivitiesLocked(pkg, newIntents, chatty);addReceiversLocked(pkg, chatty);addProvidersLocked(pkg, chatty);addServicesLocked(pkg, chatty);}......
}

Intent

startActivity()最终都会调用到startActivityForResult()

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {if (mParent == null) {options = transferSpringboardActivityOptions(options);Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this,intent, requestCode, options);if (ar != null) {mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(),ar.getResultData());}if (requestCode >= 0) {mStartedActivity = true;}cancelInputsAndStartExitTransition(options);}......
}

上面调用Instrumentation的execStartActivity()

public ActivityResult execStartActivity(......) {......try {......int result = ActivityTaskManager.getService().startActivity(whoThread,who.getBasePackageName(), who.getAttributionTag(), intent,intent.resolveTypeIfNeeded(who.getContentResolver()), token,target != null ? target.mEmbeddedID : null, requestCode, 0, null, options);checkStartActivityResult(result, intent);} catch (RemoteException e) {throw new RuntimeException("Failure from system", e);}return null;
}

上面获取ActivityTaskManagerService,是IPC过程,调用其startActivity()启动,然后调到startActivityAsUser()

private int startActivityAsUser(......) {......return getActivityStartController().obtainStarter(intent, "startActivityAsUser").setCaller(caller).setCallingPackage(callingPackage).setCallingFeatureId(callingFeatureId).setResolvedType(resolvedType).setResultTo(resultTo).setResultWho(resultWho).setRequestCode(requestCode).setStartFlags(startFlags).setProfilerInfo(profilerInfo).setActivityOptions(bOptions).setUserId(userId).execute();
}

上面通过ActivityStartController获取ActivityStarter,调用execute()

int execute() {try {......if (mRequest.activityInfo == null) {mRequest.resolveActivity(mSupervisor);}int res;synchronized (mService.mGlobalLock) {......res = executeRequest(mRequest);......return getExternalResult(mRequest.waitResult == null ? res: waitForResult(res, mLastStartActivityRecord));}}......
}

通过ActivityStartController的resolveActivity()解析Intent解析再匹配到对应的ActivityInfo,后面通过executeRequest()启动Activity

void resolveActivity(ActivityStackSupervisor supervisor) {......resolveInfo = supervisor.resolveIntent(intent, resolvedType, userId,0 /* matchFlags */,computeResolveFilterUid(callingUid, realCallingUid, filterCallingUid));......activityInfo = supervisor.resolveActivity(intent, resolveInfo, startFlags,profilerInfo);if (activityInfo != null) {intentGrants = supervisor.mService.mUgmInternal.checkGrantUriPermissionFromIntent(intent, resolvedCallingUid, activityInfo.applicationInfo.packageName,UserHandle.getUserId(activityInfo.applicationInfo.uid));}
}

调用到ActivityStackSupervisor的resolveIntent()

ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags, int filterCallingUid) {try {......try {return mService.getPackageManagerInternalLocked().resolveIntent(intent, resolvedType, modifiedFlags, privateResolveFlags, userId, true,filterCallingUid);}......}......
}

调用到PackageManagerService的resolveIntent()、resolveIntentInternal()、resolveIntentInternal()

private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags, int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits) {......final String pkgName = intent.getPackage();ComponentName comp = intent.getComponent();......if (comp != null) {		// ComponentName不为空,显式启动Activityfinal List<ResolveInfo> list = new ArrayList<>(1);final ActivityInfo ai = getActivityInfo(comp, flags, userId);if (ai != null) {......if (......) {final ResolveInfo ri = new ResolveInfo();ri.activityInfo = ai;list.add(ri);}}List<ResolveInfo> result = applyPostResolutionFilter(list, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,userId, intent);return result;}//ComponentName为空,下面进行隐式启动boolean sortResult = false;		//若有多个匹配,则需要排序boolean addInstant = false;List<ResolveInfo> result;synchronized (mLock) {if (pkgName == null) {		//包名为空,匹配schema、data等.....result = filterIfNotSystemUser(mComponentResolver.queryActivities(intent, resolvedType, flags, userId), userId);......if (intent.hasWebURI()) {		//处理http标签......}} else {		//包名不为空则获取PackageManagerService解析到的PackageSettingfinal PackageSetting setting = getPackageSettingInternal(pkgName, Process.SYSTEM_UID);result = null;if (setting != null && setting.pkg != null && (resolveForStart  || !shouldFilterApplicationLocked(setting, filterCallingUid, userId))) {result = filterIfNotSystemUser(mComponentResolver.queryActivities(intent, resolvedType, flags, setting.pkg.getActivities(), userId), userId);}if (result == null || result.size() == 0) {  //若未通过PackageManagerService解析,则可能是第三方安装的应用addInstant = isInstantAppResolutionAllowed(intent, null /*result*/, userId, true /*skipPackageCheck*/);if (result == null) {result = new ArrayList<>();}}}}if (addInstant) {	//处理第三方应用String callingPkgName = getInstantAppPackageName(filterCallingUid);boolean isRequesterInstantApp = isInstantApp(callingPkgName, userId);result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId,resolveForStart, isRequesterInstantApp);}if (sortResult) {Collections.sort(result, RESOLVE_PRIORITY_SORTER);}return applyPostResolutionFilter(result, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,userId, intent);
}

PackageManagerService解析AndroidManifest时会将四大组件存到mComponentResolver,调用其queryActivities()从mActivities取出ResolveInfo

@Nullable
List<ResolveInfo> queryActivities(Intent intent, String resolvedType, int flags,int userId) {synchronized (mLock) {return mActivities.queryIntent(intent, resolvedType, flags, userId);}
}@Nullable
List<ResolveInfo> queryActivities(Intent intent, String resolvedType, int flags,List<ParsedActivity> activities, int userId) {synchronized (mLock) {return mActivities.queryIntentForPackage(intent, resolvedType, flags, activities, userId);}
}

http://www.ppmy.cn/news/1124623.html

相关文章

k8s-2 集群升级

首先导入镜像到本地 然后上传镜像到仓库 在所有集群节点 部署cri-docker k8s从1.24版本开始移除了dockershim&#xff0c;所以需要安装cri-docker插件才能使用docker 配置cri-docker 升级master 节点 升级kubeadm 执行升级计划 修改节点套接字 腾空节点 升级kubelet 配置k…

‘Xcode Unable to execute command: Segmentation fault: 11‘

概述, Xcode Unable to execute command: Segmentation fault: 11 解决方案, 添加: Build Setting -> Other Linker Flags -> -ld64 延伸, -ld64是什么, 在 Xcode 的 Build Setting 中&#xff0c;Other Linker Flags&#xff08;其他链接器标志&#xff09;用于向链…

Redis---第一篇

系列文章目录 文章目录 系列文章目录一、RDB 和 AOF 机制二、Redis的过期键的删除策略一、RDB 和 AOF 机制 RDB:Redis DataBase 在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写 入临时文件,写入成功后,再替换之前的文件,用…

原生js值之数据类型详解

js的数据类型 数据类型分类基本数据类型boolean:布尔类undefined:未定义的值null类型数值转换 NumberparseInt 转换整数 parseFloat转换浮点数 String类型特点如何转换成字符串模板字面量字符串插值模板字面量标签函数 symbol类型特性使用 BigInt类型复杂数据类型Object类属性与…

Java学习笔记②

java反射 值的修改 public等属性的值的修改很简单。但private&#xff0c;final的值修改有改变。 比如修改下类的4个属性。 class privateClass {private String privateField "private value";private final String finalPrivateField "final private va…

题目 1059: 二级C语言-等差数列

题目描述 sum2581114…&#xff0c;输入正整数n&#xff0c;求sum的前n项和。样例输入 2样例输出 7 根据题目我们得知&#xff0c;求一个等差数列的和。 等差数列的下一项前一项d。d是等差。 根据这个直接求每一项&#xff0c;再加进sum的和&#xff0c;最后输出即可。 在本题中…

滨州专利申请需要的材料

国知局受理后缴纳费用 国知局一般在接到专利申请文件后的15个工作日内&#xff0c;下发受理通知书和缴费通知书。可通过网上银行、邮政汇款缴费或者面交。如果在提交申请后两个月内没有缴纳申请费的&#xff0c;该申请将视为撤回&#xff1b;缴费成功后&#xff0c;该专利申请进…

SMT贴片加物料损耗原因及解决方案

1、安装元件物料时撕料带过长&#xff0c;压料过多造成不必要的物料遗失损耗 解决方式&#xff1a;培训操作人员作业时&#xff0c;装料时保留两三个空位&#xff0c;压料至料窗可见物料即可&#xff0c;这样就可以检查FEEDER齿轮位置和卷带张力。 2、FEEDER安装后TABLE上有杂…