1.通过ADB INSTALL(选项-s 代表安装到SD卡上)
2.Pm install 。
以上俩个最后都是调用Pm.java/main
3.手机里点击安装,首先调用PackageInstallerActivity
以上三种最终调到
1.framewrok/PackageManagerService.java
public void installPackageWithVerification(Uri packageURI, IPackageInstallObserver observer,
int flags, String installerPackageName, Uri verificationURI,
ManifestDigest manifestDigest)
关键参数flags
PackageManager.INSTALL_REPLACE_EXISTING
PackageManager.INSTALL_INTERNAL
this package has to be installed on the sdcard.
PackageManager. INSTALL_EXTERNAL
PackageManagerService初次创建时候起了一个新线程HandlerThread,以及与其关联的PackageHandler
在这个函数中像这个HANDLER发送消息INIT_COPY(带有构造好的安装信息对象),安装过程将会在线程中完成。
2. 在接受到INIT_COPY后
启动远程DefaultContainerService,然后把安装信息放到一个LIST里,再次给本线程HANDLER发送消息MCS_BOUND
3.在接受到MCS_BOUND后
从LIST里取出第一个对象开始干活,干活完毕后再次发送MCS_BOUND,再回到本处理,又一次取LIST里的第一个继续干活,直到干完。
4.正式开始干了。
首先完成拷贝
/*
* Invoke remote method to get package information and install
* location values. Override install location based on default
* policy if needed and then create install arguments based
* on the install location.
*/
InstallParams。handleStartCopy(){}
其中一个重要的调用是DefaultContainerService。public PackageInfoLite getMinimalPackageInfo(final Uri fileUri, int flags, long threshold)
这个函数干了点什么呢,
首先安装包的时候,根据-S选项等,有一个flag,是选择安装到哪里(外部或内部),然后在这个函数里,会解析APK里的MANIFEST,会解析
installLocation,这里有一个安装位置,根据这俩个综合的出
prefer = PREFER_INTERNAL OR prefer = PREFER_EXTERNAL
第2件事是判断这个包有没有超过他要安装位置的存储空间,
比如装在内部要判断isUnderInternalThreshold,装在外卡要判断isUnderExternalThreshold(apkFile);
最后返回一个整形数给handleStartCopy,
继续,调用installLocationPolicy(pkgLite, flags);综合的出这个LOC应该是在外还是内。根据此创建一个安装对象
new SdInstallArgs(params); OR new FileInstallArgs(params)
然后调用这个安装对象的copyApk(mContainerService, true);