Android70 PackageManagerService 3 APK安装一.docx

上传人:b****5 文档编号:2824661 上传时间:2022-11-15 格式:DOCX 页数:27 大小:93.48KB
下载 相关 举报
Android70 PackageManagerService 3 APK安装一.docx_第1页
第1页 / 共27页
Android70 PackageManagerService 3 APK安装一.docx_第2页
第2页 / 共27页
Android70 PackageManagerService 3 APK安装一.docx_第3页
第3页 / 共27页
Android70 PackageManagerService 3 APK安装一.docx_第4页
第4页 / 共27页
Android70 PackageManagerService 3 APK安装一.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

Android70 PackageManagerService 3 APK安装一.docx

《Android70 PackageManagerService 3 APK安装一.docx》由会员分享,可在线阅读,更多相关《Android70 PackageManagerService 3 APK安装一.docx(27页珍藏版)》请在冰豆网上搜索。

Android70 PackageManagerService 3 APK安装一.docx

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:

:

vectorapk_file={argv[last_apk]};

//构造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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1