packagesappsPackageInstaller下InstallAppProgress.java调用installPackageWithVerificationAndEncryption()正式进入PackageManagerService.java。
PackageManagerService类中installPackageWithVerificationAndEncryption()中有一个
final Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams();
进入PackageHandler类的handleMessage()方法,handleMessage()会调用doHandleMessage()方法,处理INIT_COPY消息,之后再handleMessage(),doHandleMessage(),处理MSC_BOUND。在处理MSC_BOUND消息时,会调用params.startCopy()方法,params是HandlerParams对象。startCopy()方法中会调用handleStartCopy()方法,由此进入InstallParams的handleStartCopy()方法。
handleStartCopy()方法通常会直接进入
if (packageFile != null) {
// Remotecall to find out default install location
finalString packageFilePath = packageFile.getAbsolutePath();
pkgLite =mContainerService.getMinimalPackageInfo(packageFilePath, flags,
lowThreshold);
...}这段。重点看下pkgLite的初始化过程,即pkgLite =mContainerService.getMinimalPackageInfo(packageFilePath,flags,lowThreshold);mContainerService是IMediaContainerService对象,从IMediaContainerService类的起名就可以看出,这个类不可能有实例化对象,实例化的对象必然要有它的实现类来初始化,对应的类是DefaultContainerService.java,DefaultContainerService.java中getMinimalPackageInfo()调用PackageParser.parsePackageLite()得到PackageParser.PackageLite信息,从而初始化PackageInfoLiteret信息,其中PackageInfoLite的ret.recommendedInstallLocation信息尤其关键,它决定了应用安装的位置。详细看下ret.recommendedInstallLocation的获取过程,recommendAppInstallLocation()方法。recommendAppInstallLocation()这个函数根据packageInfo的installLocation和flags两个信息找出最佳安装位置,即PackageHelper.RECOMMEND_INSTALL_INTERNAL或PackageHelper.RECOMMEND_INSTALL_EXTERNAL。对应data区和SD卡区。一切正常,流程到if (ret == PackageManager.INSTALL_SUCCEEDED) { int loc =pkgLite.recommendedInstallLocation; Log.d(TAG,"[handleStartCopy]---gaoyh loc =" + loc); if (loc ==PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) { ret =PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; } else if (loc ==PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) { ret =PackageManager.INSTALL_FAILED_ALREADY_EXISTS; } else if (loc ==PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { ret =PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; 。。。}过程,通常情况下,package的flags值为0,那么位置选择为PackageHelper.RECOMMEND_INSTALL_INTERNAL,进入} else if (!onSd && !onInt) { //Override install location with flags if (loc ==PackageHelper.RECOMMEND_INSTALL_EXTERNAL) { // Set the flag to install onexternal media. flags |=PackageManager.INSTALL_EXTERNAL; flags &=~PackageManager.INSTALL_INTERNAL; } else{ // Make sure the flag forinstalling on external // media is unset flags |=PackageManager.INSTALL_INTERNAL; flags &=~PackageManager.INSTALL_EXTERNAL; Log.d(TAG,"[handleStartCopy]---gaoyh new flags =" + flags); } }中的else代码段,flags |=PackageManager.INSTALL_INTERNAL;flags &=~PackageManager.INSTALL_EXTERNAL;之后 final InstallArgs args= createInstallArgs(this);选择FileInstallArgs作为实现类,再往下跟,if (requiredUid != -1 &&isVerificationEnabled(flags)) {}这个通常是不走的,从而程序直接进入 ret = args.copyApk(mContainerService,true);过程。