Android app安装过程分析(基于Nougat)

首先我们要清楚总体可以分成如下几种安装的情况
* 系统开机的应用安装,安装的是系统级别的应用,用户在没有获取到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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值