Android中级——PackageManagerService和Intent

PackageManagerService和Intent

  • PackageManagerService
  • Intent

PackageManagerService

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

......
if (partition.getPrivAppFolder() != null) {		//扫描系统应用,路径/system/priv-app
    scanDirTracedLI(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 parseBaseApkTags(ParseInput input, ParsingPackage pkg, TypedArray sa, Resources res, XmlResourceParser parser, int flags) throws XmlPullParserException, IOException {
    ParseResult 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(" has more than one ");
                } else {
                    Slog.w(TAG, " has more than one ");
                    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 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 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":		// 解析Activity
                isActivity = true;
                // fall-through
            case "receiver":	// 解析receiver
                ParseResult 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":	// 解析service
                ParseResult 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":		// 解析provider
                ParseResult 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 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 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不为空,显式启动Activity
        final List 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 result = applyPostResolutionFilter(
                list, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
                userId, intent);
        return result;
    }
	
	//ComponentName为空,下面进行隐式启动
    boolean sortResult = false;		//若有多个匹配,则需要排序
    boolean addInstant = false;
    List result;
    synchronized (mLock) {
        if (pkgName == null) {		//包名为空,匹配schema、data等
            .....
            result = filterIfNotSystemUser(mComponentResolver.queryActivities(
                    intent, resolvedType, flags, userId), userId);
           	......
            if (intent.hasWebURI()) {		//处理http标签
                ......
            }
        } else {		//包名不为空则获取PackageManagerService解析到的PackageSetting
            final 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 queryActivities(Intent intent, String resolvedType, int flags,
        int userId) {
    synchronized (mLock) {
        return mActivities.queryIntent(intent, resolvedType, flags, userId);
    }
}

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

你可能感兴趣的:(#,Android中级,android,java,linux)