首先我们要清楚总体可以分成如下几种安装的情况
* 系统开机的应用安装,安装的是系统级别的应用,用户在没有获取到root权限的情况下无法卸载的应用
* adb安装的应用,没有安装界面
* 第三方市场下载的应用,此处要分情况,部分是通过电脑的客户端安装的没有安装的界面,部分是手机上的市场安装的,会有安装的界面
那么我们就对几种情况一一分析它的安装流程
### 开机安装
1. 首先在开机的时候systemServer会启动PackageMangerService来
具体是通过systemServer的main()->init1()->init2()->new ServerThread()->构建PMS
以上都是SystemServer.cpp中的代码,了解即可。我们前往PMS查看接下去的逻辑:在PMS的构造方法中我们看到了一大坨的逻辑
,源码过于长,我们直接在构造方法里面搜索如下这两个方法:
scanDirTracedLI //最后还是会调用下面的方法,只是对下面的方法做一下跟踪
scanDirLI
就是通过这两个方法进行应用的安装,从scanDirLI开始追踪:
private void scanDirLI(File dir, final int parseFlags, int scanFlags, long currentTime) {
final File[] files = dir.listFiles();
...
for (File file : files) {
final boolean isPackage = (isApkFile(file) || file.isDirectory())
&& !PackageInstallerService.isStageName(file.getName());
if (!isPackage) {
// Ignore entries which are not packages
continue;
}
try {
scanPackageTracedLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
scanFlags, currentTime, null);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
// Delete invalid userdata apps
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM) == 0 &&
e.error == PackageManager.INSTALL_FAILED_INVALID_APK) {
logCriticalInfo(Log.WARN, "Deleting invalid package at " + file);
removeCodePathLI(file);
}
}
}
}
继续看scanPackageTracedLI方法:
private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
long currentTime, UserHandle user) throws PackageManagerException {
if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
PackageParser pp = new PackageParser();
pp.setSeparateProcesses(mSeparateProcesses);
pp.setOnlyCoreApps(mOnlyCore);
pp.setDisplayMetrics(mMetrics);
if ((scanFlags & SCAN_TRUSTED_OVERLAY) != 0) {
parseFlags |= PackageParser.PARSE_TRUSTED_OVERLAY;
}
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
final PackageParser.Package pkg;
try {
pkg = pp.parsePackage(scanFile, parseFlags);
} catch (PackageParserException e) {
throw PackageManagerException.from(e);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
return scanPackageLI(pkg, scanFile, parseFlags, scanFlags, currentTime, user);
}
我们看到从这个方法开始parsePackage, 通过PackageParser解析apk文件,我们可以去到PackageParser的文件中看到这个parsePackage方法就是把安装包中的配置文件解析出来,并且保存到Package中返回出来,中间辗转反侧对于配置文件各种分情况进行parse,最最主要的是parseBaseApkCommon方法,这个方法对manifast文件的标签进行解析,而其中还调用了parseBaseApplication方法对application标签进行解析。
然后再scanPackageLI->scanPackageDirtyLI,在后者的方法中,我们会把之前解析出来的
PackageParser.Provider p = pkg.providers.get(i);
p.info.processName = fixProcessName(pkg.applicationInfo.processName,
p.info.processName, pkg.applicationInfo.uid);
mProviders.addProvider(p);
PackageParser.Service s = pkg.services.get(i);
s.info.processName = fixProcessName(pkg.applicationInfo.processName,
s.info.processName, pkg.applicationInfo.uid);
mServices.addService(s);
等等,我们会把相应的provider,service,receiver,activity全都保存到PMS的成员集合类中去.
至此系统应用的安装算是全部完成了,也许你会说我们并有看到什么install的什么方法,其实最最精髓的就是上面最后那一坨1000+行的方法,这里面把所有parser出来的信息全部保存到PMS中去了,而这就是所谓的安装,安装就是一个吧apk中的信息解析出来保存给PMS的过程,然后在launcher上生成一个图标,以供用户打开,仅此而已。
从网络上下载应用安装
最终都是通过如下的方式去进行安装的
String fileName = "/mnt/usb/sda4/test.apk";
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(fileName)), "application/vnd.android.package-archive");
startActivity(intent);
启动的就是PackageInstallerActivity,而这个activity是Android的系统应用之一,源码在package/app/packageinstaller中,具体源码可以前往下面链接查看:
https://github.com/android/platform_packages_apps_packageinstaller/blob/master/src/com/android/packageinstaller/PackageInstallerActivity.java
我们在其onCreate方法中看到之后会调用checkIfAllowedAndInitiateInstall->initiateInstall-> startInstallConfirm,会处理有关权限的一些问题
之后如果我们点击下方的ok按钮,会进入到安装流程:
public void onClick(View v) {
if (v == mOk) {
if (mOkCanInstall || mScrollView == null) {
i