Android70 PackageManagerService 3 APK安装一.docx
- 文档编号:2824661
- 上传时间:2022-11-15
- 格式:DOCX
- 页数:27
- 大小:93.48KB
Android70 PackageManagerService 3 APK安装一.docx
《Android70 PackageManagerService 3 APK安装一.docx》由会员分享,可在线阅读,更多相关《Android70 PackageManagerService 3 APK安装一.docx(27页珍藏版)》请在冰豆网上搜索。
Android70PackageManagerService3APK安装一
Android7.0PackageManagerService(3)APK安装
(一)
一、adb命令
看看system/core/adb/commandline.cpp中的adb_commandline函数:
intadb_commandline(intargc,constchar**argv){
...........
elseif(!
strcmp(argv[0],"install")){
if(argc<2)returnusage();
FeatureSetfeatures;
std:
:
stringerror;
if(!
adb_get_feature_set(&features,&error)){
fprintf(stderr,"error:
%s\n",error.c_str());
return1;
}
if(CanUseFeature(features,kFeatureCmd)){
//支持FeatureCmd时调用install_app
returninstall_app(transport_type,serial,argc,argv);
}
//否则,利用install_app_legacy
returninstall_app_legacy(transport_type,serial,argc,argv);
}
...........
}
1、install_app_legacy
我看先看看传统的install_app_legacy:
staticintinstall_app_legacy(TransportTypetransport,constchar*serial,intargc,constchar**argv){
//待安装的APK目前还在源机器上,现在需要把APK的文件复制到手机里
//如果安装在手机内部存储,那么目的地址为DATA_DEST
//如果安装在SD卡上,则目的地址为SD_DEST
staticconstchar*constDATA_DEST="/data/local/tmp/%s";
staticconstchar*constSD_DEST="/sdcard/tmp/%s";
.........
//默认安装到手机内部
constchar*where=DATA_DEST;
for(i=1;i //携带参数-s时,才安装到SD卡 if(! strcmp(argv[i],"-s")){ where=SD_DEST; } } //解析参数,判断adb命令中是否携带了有效的apk文件名 ........... //取出apk名 std: : vector //构造apk目的地址 std: : stringapk_dest=android: : base: : StringPrintf( where,adb_basename(argv[last_apk]).c_str()); //do_sync_push将此APK文件传输到手机的目标路径,失败的话将跳转到clenaup_apk if(! do_sync_push(apk_file,apk_dest.c_str()))gotocleanup_apk; //执行pm_command result=pm_command(transport,serial,argc,argv); cleanup_apk: //删除刚才传输的文件 //PKMS在安装过程中会将该APK复制一份到/data/app目录下,所有data/local/tmp目录下对应的文件可以删除 delete_file(transport,serial,apk_dest); returnresult; } 从代码来看,传统的安装方式就是将源机器中的APK文件拷贝到目的手机的tmp目录下,然后调用pm_command进行处理。 2、install_app 我们再看看支持FeatureCmd的机器,如何安装APK: staticintinstall_app(TransportTypetransport,constchar*serial,intargc,constchar**argv){ //利用参数创建出本地文件的名称 constchar*file=argv[argc-1]; //解析参数,判断adb命令中是否携带了有效的apk文件名 ......... //adb_open中将创建出这个file对应的文件 intlocalFd=adb_open(file,O_RDONLY); ............ std: : stringcmd="exec: cmdpackage"; //添加cmd参数 ............ //连接源端,获取源APK文件的描述符 intremoteFd=adb_connect(cmd,&error); ............ //将remoteFd中的数据写入到localFd copy_to_file(localFd,remoteFd); //得到结果 read_status_line(remoteFd,buf,sizeof(buf)); adb_close(localFd); adb_close(remoteFd); .......... return0; } 从代码来看install_app就是将源机器的文件复制到了目的机器中,并没有进行额外的操作。 猜想可能是支持特殊FeatureCmd的机器,PKMS能够监听到这个拷贝,然后触发后续的扫描工作。 这个过程没有研究过对应代码,暂时不做深入分析。 对于传统的安装方式,我们需要继续往下看看pm_command。 二、pm_command 我们先看看pm_command函数: staticintpm_command(TransportTypetransport,constchar*serial,intargc,constchar**argv){ std: : stringcmd="pm"; //构造pmcmd while(argc-->0){ cmd+=""+escape_arg(*argv++); } //发送shell命令给adbd returnsend_shell_command(transport,serial,cmd,false); } 我们跟进下send_shell_command: //Connectstothedevice"shell"servicewith|command|andprintsthe //resultingoutput. staticintsend_shell_command(TransportTypetransport_type,constchar*serial, conststd: : string&command, booldisable_shell_protocol, std: : string*output=nullptr, std: : string*err=nullptr){ ........... while(true){ boolattempt_connection=true; //Useshellprotocolifit'ssupportedandthecallerdoesn'texplicitlydisableit. if(! disable_shell_protocol){ ....... if(adb_get_feature_set(&features,&error)){ //如果定义了feature,则替换shellprotocol use_shell_protocol=CanUseFeature(features,kFeatureShell2); }else{ //Devicewasunreachable. attempt_connection=false; } } if(attempt_connection){ std: : stringerror; //此时command中携带的就是以pm开头的命令 std: : stringservice_string=ShellServiceString(use_shell_protocol,"",command); //向shell服务发送命令 fd=adb_connect(service_string,&error); if(fd>=0){ break; } } ............ } //读取返回结果 intexit_code=read_and_dump(fd,use_shell_protocol,output,err); if(adb_close(fd)<0){ .......... } returnintexit_code; } 从上面的代码来看,pm_command就是向shell服务发送pm命令。 pm是一个可执行脚本,我们在终端上调用adbshell,然后执行pm,可以得到以下结果: root: /#pm usage: pmlistpackages[-f][-d][-e][-s][-3][-i][-u][--userUSER_ID][FILTER] pmlistpermission-groups pmlistpermissions[-g][-f][-d][-u][GROUP] pmlistinstrumentation[-f][TARGET-PACKAGE] .......... pm脚本定义在frameworks/base/cmds/pm中: base=/system exportCLASSPATH=$base/framework/pm.jar execapp_process$base/binmands.pm.Pm"$@" 在编译system.img时,会根据Android.mk将该脚本复制到system/bin目录下。 从脚本的内容来看,当调用pm时,将向app_process目录的main函数传入Pm对应的参数: 我们看看对应的定义于app_main.cpp的main函数(前面的博客分析过,这个其实也是zygote启动的函数): //app_process的main函数 intmain(intargc,char*constargv[]){ ........ //解析参数 while(i constchar*arg=argv[i++]; if(strcmp(arg,"--zygot
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android70 PackageManagerService APK安装一 APK 安装