Android学习之APK的安装流程

代码不是连续的。

开始。

adb install *.apk.

1,commandline.c

int adb_commandline(int argc, char **argv){
...
if(!strcmp(argv[0],"install")){
return install_app(ttpye,serial,argc,argv);
}
...
}
int install_app(transport_type transport,char * serial,int argc,char ** argv){
static const char *const DATA_DEST = "/data/local/tmp/%s"
static const char *const SD_DEST = "/sdcard/tmp/%s"
...
apk_file = argv[file_arg];//获取apk全路径:/../*.apk
//将apk传送到手机的目标路径
err = do_sync_push(apk_file,apk_dest,1/*verify APK */);
//执行脚本pm,安装apk
pm_command(transport,serial,argc,argv);
//delete that apk
delete_file(transport,serial,apk_dest);
}
static int pm_command(...){
//执行pm.java的main()
send_shellcommand(transport,serial,buf);
}
2,pm.java

public static void main(String[] args){
new Pm().run(args);
}
public void run(String[] args){
//获取PKMS的binder客户端
mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
...
runInstall();//安装
...
}
private void runInstall(){
...
//监视安装情况
PackageInstallObserver obs = new PackageInstallObserver()
try{//安装
mPm.installPackageWithVerification(apkURI,obs,installFlags,installerPackageName,verificationURI,null);
...
}
}
}

3,PackageManagerService.java

public void installPackageWithVerification(...){
...
//mHandler之前提过,构造函数的时候开启的,用于apk的安装卸载
final Message msg = mHandler.obtainMessage(INIT_COPY);
msg.obj = new InstallParams(packageURI,observer,filteredFlags,installerPackageName,verificationURI,manifestDigest):
mHandler.sendMessage(msg);
}
public void handleMessage(Message msg){
try{
doHandleMessage(msg);
}
}
void doHandleMessage(Message msg){
...
case INIT_COPY:
//先处理等待安装的包
int idx = mPendingInstalls.size()
//连接到DefaultContainerService服务,主要作用是为apk选择最好的安装位置。
if(!connectToSerivice())
//存在等待安装的包就把这个apk加到等待队里
mPendingInstalls.add(idx,params);
//没有等待的包就安装
mHandler.sendEmptyMessage(MCS_BOUND);
case MCS_BOUND:
...
if(params.startCopy())//安装
...
}
final boolean startCopy(){
...
handleStartCopy();
...
handleReturnCode();
//处理安装完毕 
case POST_INSTALL:
//会判断是否是update,在extras里区分
//发送PACKAGE_ADDED广播
sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,res.pkg.applicationInfo.packageName,extras,null,null);
...
//清理资源
res.removedInfo.args.doPostDeleteLI(true);
...
//通知pm安装结果
args.observer.packageInstalled(res.name,res.returnCode);
}
public void handleStartCopy(){//InstallParams.handleStartCopy
//一系列检查判断,安装位置SD卡or Interanl存储
//存储空间剩余量
...
//得到PackageInfoLite对象。这个对象继承自Parcelable,用于描述apk的结构
pkgLite = mContainerService.getMinimalPackageInfo(packageURI,flags,lowThreshold);
//获得apk的建议路径
int loc = pkgLite.recommendedInstallLocation;
...
//创建InstallArgs对象,Internal存储为FileInstallArgs ,SD卡存储为SdInstallArgs.
final InstallArgs args = createInstallArgs(this);
...
ret = args.copyApk(mContainerService,true);//安装
}
void handleReturnCode(){//InstallParams.HandleParams
...
processPendingInstall(mArgs,mRet);
}
private void processPendingInstall(...){
mHandler.post(new Runnable(){
public void run(){
...
args.doPreInstall(res.returnCode);//上面的mArgs
synchronized(mInstallLock){
installPackageLI(args,true,res);//安装
}
args.doPostInstall(res.returnCode);
...
//安装完毕发消息 
Message msg = mHandler.obtainMessage(POST_INSTALL,token,0);
mHandler.sendMessage(msg);
}
});
}
private void installPackageLI(...){
//做了两个主要操作
//1,调用doRename对临时文件进行改名。
if(!args.doRename(res.returnCode,pkgName,oldCodePath))
//2,安装:replace or install new
//无论是哪个最终会调用上一节学习PKMS构造函数时调用的核心函数scanPackageLI(),完成自己apk信息上报,公有化。apk安装完毕。
if(replace){
replacePackageLI(...);
}esle{
installNewPackageLI(...)
}
}


4,DefaultContainerService.java

3中涉及的几个函数。

public PackageInfoLite getMinimalPackageInfo(...){
PackageInfoLite ret = new PackageInfoLite();
...
//archiveFilePath由传进来的fileUri即packURI获得,fileUri指向/data/local/tmp/*.apk
String archiveFilePath = fileUri.getPath();
PackageParser.PackageLite pkg = PackageParser.parsePackageLite(archiveFilePath,0);
ret.recommandedInstallLocation = recommendAppInstallLocation(pkg.installLocation,archiveFilePath,flags,threshold);
private int recommandAppInstallLocation(...){
int prefer;//最好的位置
//在
//pkg.installLocation
check_inner:{
...
}
//和Settings数据库中设置的安装位置
int installPreference = Settings.System.getInt();
}
//中选择
...
//最后判断是否有足够空间
...
}



最后上个萌图



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值