Android中级——PackageManagerService和Intent

PackageManagerService和Intent

PackageManagerService

从SystemService的main()方法开始执行

public static void main(String[] args) {
    new SystemServer().run();
}

调用run()

private void run() {
    ......
    try {
        startBootstrapServices(t);
        ......
    }......
}

调用startBootstrapServices()

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
    ......
    try {
        ......
        mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
    }......
}

调用PackageManagerService的main()方法

public static PackageManagerService main(Context context, Installer installer,
        boolean factoryTest, boolean onlyCore) {
    ......
    PackageManagerService m = new PackageManagerService(injector, onlyCore, factoryTest);
	 ......
    ServiceManager.addService("package", m);
	......
    return m;
}

PackageManagerService的构造函数解析其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<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":		// 解析Activity
                isActivity = true;
                // fall-through
            case "receiver":	// 解析receiver
                ParseResult<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":	// 解析service
                ParseResult<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":		// 解析provider
                ParseResult<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不为空,显式启动Activity
        final 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解析到的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<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);
    }
}
Android PackageManagerserviceAndroid 系统中的一个服务,它负责管理应用程序包。PackageManagerservice 提供了许多功能,包括安装、卸载、更新和管理应用程序的权限等。下面对其功能进行详细解释: 1. 安装应用程序:PackageManagerservice 能够将应用程序的 APK 文件安装到设备中。当用户从 Google Play 商店或其他渠道下载应用程序时,PackageManagerservice 将应用程序文件正确安装到手机的存储区域中。 2. 卸载应用程序:PackageManagerservice 可以卸载设备上的应用程序。当用户要卸载一个应用程序时,PackageManagerservice 会检查该应用程序的包名及其相关文件,并将其从设备中删除。 3. 更新应用程序:PackageManagerservice 能够更新已经安装在设备上的应用程序。当用户从应用商店下载一个已经安装的应用程序的更新时,PackageManagerservice 将下载的新版本进行安装,以替换旧版本。 4. 管理应用程序权限:PackageManagerservice 配合 Android 系统的权限系统,控制应用程序的权限。用户给予应用程序某些权限后,PackageManagerservice 会验证和授权应用程序的权限使用,确保应用程序的安全性和隐私保护。 除此之外,PackageManagerservice 还负责处理应用程序的签名验证、计算应用程序的版本号和版本名、管理应用程序的组件(如活动、服务等),以及处理应用程序之间的相互调用等。 总之,Android PackageManagerserviceAndroid 系统中的一个重要服务,负责管理应用程序的安装、卸载、更新和权限管理等功能。它的存在确保了 Android 应用生态的安全和稳定运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值