1. 应用安装的几种途径:
1.系统开机的应用安装,安装的是系统级别的应用,用户在没有获取到root权限的情况下无法卸载的应用
2.adb安装的应用,没有安装界面
3.第三方市场下载的应用:部分是通过电脑的客户端安装的没有安装的界面,部分是手机上的市场安装的,会有安装的界面。
1.1 .开机安装APP:
1.SystemServer 启动PKMS
1.SystemServer 中创建installer对象,传入PKMS 的实例中;
2.创建PKMS 实例时,传入mFactoryTestMode,判断是否是工厂模式?(工厂测试模式下有什么区别???)
3.创建PKMS 实例时,传入mOnlyCore , 涉及加密流程
4.此进程完成对 /system/app,/data/app,/system/framework,/data/app-private 下的 apk 文件的解析
2.AndroidManifest.xml 中记录的packageInfo 信息,实际上和PKMS.getPackageInfo() 的返回值是一一对应的。
packageInfo 类中包含package 以及包中activity 信息。[类似于AndroidManifest中一层层包含]
applicationInfo 类对应的就是AndroidManifest.xml 中对应application 下的信息
activityInfo 类对应的就是AndroidManifest.xml 中对应activity 下的信息
****************************************************************************************************************************
2.源码流程解析
//https://blog.csdn.net/csdn_of_coder/article/details/74025409
1.adb install --->system/core/adb/commandline.cpp::install_app()
... 1.确定2个拷贝文件的位置,默认拷贝到内部
... 2.将制定的apk文件从电脑端拷贝到制定的目录处
1.安装到data目录下时,会将apk先拷贝一份到"/data/local/tmp/%s"目录下;
... 3.执行pm 脚本,调用pm_command()函数开始去安装
... 4.当安装结束时删除该apk文件
... 5.手机的端的adbd程序接收到客户机发送的shell pm命令后,会开启一个shell去执行pm脚本.
1.编译时会被打包成/system/bin/pm可执行程序,执行pm可执行程序其实就是执行这段脚本
2.我们传入的是install命令,所以执行runInstall()函数;至此,安装过程就即将进入PackageManagerService了
2.PackageManager::installPackage()函数安装应用:
PackageManager.installPackage
--->ApplicationPackageManager.installPackage
【ApplicationPackageManager 复写了PackageManager】
--->PackageManager.PackageInstallObserver
1.【它是用户用来监听APK安装的最后结果的】
2.【当apk安装结束时,系统会回调PackageManager.PackageInstallObserver.onPackageInstalled()接口通知用户当前apk安装的结果信息】
--->PackageManagerService.installPackageAsUser
1.检测权限:UserManager.DISALLOW_INSTALL_APPS ,多用户情况下...
2.callingUid =Process.SHELL_UID ||callingUid == Process.ROOT_UID 时,增加PM.INSTALL_FROM_ADB的flags...
3.多用户安装:如果带有INSASLL_ALL_USERS标记,则给所有用户安装
4.初始化【InstallParams】 对象实例,将安装参数信息保存到InstallParams对象中
1.final Message msg = mHandler.obtainMessage(INIT_COPY)
2.final InstallParams params = new InstallParams( ... ...)
3.msg.obj = params
5.接着会发送INIT_COPY消息到Handler进行处理
--->PackageManagerService.PackageHandler【PKMS 中专门处理install相关的handler】
... case INIT_COPY:
1.检测是否绑定DefaultContainerService服务;
2.mPendingInstalls是PackageHandler的一个成员,它保存所有的APK安装的InstallParams【不是直接保存HandlerParams 对象,而是根据HandlerParams生成一个InstallParams,InstallParams 继承HandlerParams并实现了 abstract HandlerParams.handleStartCopy() 函数】对象;
... case MCS_BOUND:
1.DefaultContainerService服务连接正常;
2.从 mPendingInstalls 的首部拿出需要执行的安装参数信息,生成PKMS.HandlerParrams对象实例【mPendingInstalls 是PKMS 的成员变量,它直接包含的也是PKMS 的成员变量HandlerParrams】;
3.调用HandlerParrams接口,去执行apk的拷贝工作;此处是调用HandlerParams::startCopy();【尝试的次数是4次】【每个APK 的安装,都是以HandlerParams对象实例为单位进行的】
--->HandlerParams::startCopy()
--->【InstallParams继承HandlerParams】InstallParams::handleStartCopy()
1.进行一些安装标志的判断,检测onSd / onInt ;
2.调用DCS::getMinimalPackageInfo()方法获取该apk安装需要的大小及其他信息,信息会封装到PackageInfoLite对象中;检测安装的路径剩余空间,如果不足,尝试去除cache
3.以当前的InstallParams为实例,创建【FileInstallArgs对象(FileInstallArgs 是InstallParams 的内部类)】,并保存一份到InstallParams对象的mArgs字段中
---> FileInstallArgs::copyApk()
1.最终执行apk 文件的copy是DefaultContainerService::copyPackage()方法;
DCS:copyPackage
....>调用PackageParser.parsePackageLite 获取PackageLite 对象;
....>DCS.copyPackageInner
4.startCopy工作完成后,【移除】 mPendingInstalls首部内容;
5.如果mPendingInstalls已经没有内容,说明安装任务已经全部执行完毕,则会延迟10s后断开服务连接 OR 否则,会再次发送MCS_BOUND消息,处理下一个安装请求;