Android 系统启动流程分析之安装应用

ServerThread thr = new ServerThread();
thr.initAndLoop();

在initAndLoop方法里加载各种服务,比如WindowManagerService(Wms)、ActivityManagerService(Ams)、PackageManagerService(Pms)等.

看下启动PackageManagerServer的代码

pm = PackageManagerService.main(context, installer, factoryTest != SystemServer.FACTORY_TEST_OFF, onlyCore);

这个pm是IPackageManager的实例,IPackageManager是由IPackageManager.aidl文件编译生成的.

PackageManagerService继承自IPackageManager.Stub

public class PackageManagerService extends IPackageManager.Stub {

PackageManagerService调用main方法,传入四个参数

context 上下文

installer 安装器

factoryTest != SystemServer.FACTORY_TEST_OFF 是否为正常的工厂模式

onlyCore 为true表示在加密的设备只启动核心的程序

那么查看PackageManagerService的main方法.

PackageManagerService定义在frameworks/base/services/java/com/android/server/PackageManagerService.java文件中.

main方法是这样的

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

根据传入的四个参数创建PackageManagerService的实例,
然后通过ServiceManager添加这个PackageManagerService实例.

既然创建了这个实例,那么就调用了它的有参构造函数

1.在构造函数里会扫描制定目录的apk文件

// 扫描基础框架(没有代码的资源包)。				
				mFrameworkInstallObserver = new AppDirObserver(frameworkDir.getPath(), OBSERVER_EVENTS, true, false, false);
				mFrameworkInstallObserver.startWatching();
				scanDirLI(frameworkDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanMode | SCAN_NO_DEX, 0);
				
				// 扫描system/priv-app目录			 
				File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
				mPrivilegedInstallObserver = new AppDirObserver(privilegedAppDir.getPath(), OBSERVER_EVENTS, true, true, false);
				mPrivilegedInstallObserver.startWatching();
				scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR | PackageParser.PARSE_IS_PRIVILEGED, scanMode, 0);

				// 扫描system/app目录				 
				File systemAppDir = new File(Environment.getRootDirectory(), "app");
				mSystemInstallObserver = new AppDirObserver(systemAppDir.getPath(), OBSERVER_EVENTS, true, false, false);
				mSystemInstallObserver.startWatching();
				scanDirLI(systemAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);

				// 扫描映射目录
				File vendorAppDir = new File("/vendor/app");
				mVendorInstallObserver = new AppDirObserver(vendorAppDir.getPath(), OBSERVER_EVENTS, true, false, false);
				mVendorInstallObserver.startWatching();
				scanDirLI(vendorAppDir, PackageParser.PARSE_IS_SYSTEM | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode, 0);

扫描调用的方法是scanDirLI,传入四个参数,context(上下文),flag(标志),scanMode(扫描模式),currentTime(当前时间).

2.在scanDirLI方法内部会调用

PackageParser.Package pkg = scanPackageLI(file, flags | PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);

3.scanPackageLI通过解析安装包parsePackage获取到安装包的信息结构

PackageParser pp = new PackageParser(scanPath)
		pp.setSeparateProcesses(mSeparateProcesses);
		pp.setOnlyCoreApps(mOnlyCore);
		final PackageParser.Package pkg = pp.parsePackage(scanFile, scanPath, mMetrics, parseFlags);

4.之后调用parsePackage的重载方法解析,将应用信息保存在PackageManagerService,比如VersionCode、VersionName等

 try {
            // XXXX todo: need to figure out correct configuration.
            pkg = parsePackage(res, parser, flags, errorText);
        } catch (Exception e) {
            errorException = e;
            mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
        }

5.回到第3步,调用scanPackageLI的重载方法

PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_SIGNATURE, currentTime, user);6.

6.然后调用createDataDirsLI方法

// And now re-install the app.
ret = createDataDirsLI(pkgName, pkg.applicationInfo.uid, pkg.applicationInfo.seinfo);

7.在createDataDirsLI方法里调用mInstaller的install方法进行安装.

int res = mInstaller.install(packageName, uid, uid, seinfo);

    原文作者:PackageManagerService
    原文地址: https://juejin.im/entry/576b7b060a2b580058e9063a
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞