android app安装的过程,Pm install App流程

adb安装应用

应用安装涉及目录: system/app ---------------系统自带的应用程序,获得adb

root权限才能删除data/app  ---------------用户程序安装的目录。安装时把

apk文件复制到此目录data/data ---------------存放应用程序的数据data/dalvik-cache--------将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件)

adb大致有三种方式可以安装应用,分别是

adb

install, adb push 和adb shell pm

install

网上查资料说的adb

install也是使用pm命令,和adb

shell pm install方式相同,但更加简单,所以,这里统一成adb

install方式。

pm命令

使用的是pm命令进行安装,这个pm是什么个东西?

pm位于手机/system/bin/目录下,源码是frameworks/base/cmds/pm,我们看到,pm是一个很简单的shell脚本

# Script

to start "pm" on the device, which has a very rudimentary

shell.

#

base=/system

export

CLASSPATH=$base/framework/pm.jar

exec

app_process $base/bin com.android.commands.pm.Pm

"$@"

CLASSPATH指定了你的程序的位置,com.android.commands.pm.Pm则说明了程序的入口为com.android.commands.pm.Pm,即入口函数main()所在的类,"$@"就是传递给main()函数的参数,只是这里"$@"本身又是个shell传入的参数而已。

执行pm命令其实是通过运行shell脚本frameworks/base/cmds/pm/pm,然后在该脚本中运行app_process命令来启动framework/pm.jar包中的Pm这个java程序的。这个启动过程,有兴趣的同学可以看另一篇>>,这里就不在重复了,接下来,就到com.android.commands.pm.Pm类来处理参数了。

Pm类很简单,具体安装过程是在PackageManagerService中,通过调用PackageManagerService.installPackage()。adb

install xxxx.apk会通过app_process启动Pm程序,将install

xxxx.apk参数传入main()方法中。

//Pm.java

public

static void main(String[] args)

{

new Pm().run(args);

//这里args就是参数列表,如install

xxx.xxx.xxx.apk

}

public

void run() {

…………………………

mArgs = args;

//参数列表

String

op = args[0];

//取第一个参数,也就是pm后面跟着的命令

mNextArg = 1;

//下一个参数的索引

…………………………………………………………..

if ("install".equals(op))

{

runInstall();

return;

}

………………………….

}

private

void runInstall() {

int

installFlags = 0;

String installerPackageName = null;

String opt;

while

((opt=nextOption()) != null) { //

nextOption()取mNextArg当前位置的参数,比如-r

if (opt.equals("-l")) {

installFlags |=

PackageManager.INSTALL_FORWARD_LOCK;

} else if (opt.equals("-r")) {

installFlags |=

PackageManager.INSTALL_REPLACE_EXISTING;

} else if (opt.equals("-i")) {

installerPackageName = nextOptionData();

if (installerPackageName == null) {

System.err.println("Error: no value specified for

-i");

showUsage();

return;

}

} else if (opt.equals("-t")) {

installFlags |=

PackageManager.INSTALL_ALLOW_TEST;

} else if (opt.equals("-s")) {

// Override if -s option is specified.

installFlags |= PackageManager.INSTALL_EXTERNAL;

} else if (opt.equals("-f")) {

// Override if -s option is specified.

installFlags |= PackageManager.INSTALL_INTERNAL;

} else {

System.err.println("Error: Unknown option: " +

opt);

showUsage();

return;

}

}

String apkFilePath = nextArg(); //取安装包文件路径

System.err.println("\tpkg: " + apkFilePath);

if

(apkFilePath == null) {

System.err.println("Error: no package

specified");

showUsage();

return;

}

PackageInstallObserver obs = new

PackageInstallObserver();

try

{

mPm.installPackage(Uri.fromFile(new

File(apkFilePath)), obs, installFlags,

installerPackageName);

synchronized (obs)

{

//等待安装结果

while (!obs.finished) {

try

{

obs.wait();

} catch (InterruptedException e) {

}

}

if (obs.result == PackageManager.INSTALL_SUCCEEDED)

{

System.out.println("Success");

} else {

System.err.println("Failure ["+ installFailureToString(obs.result)

+ "]");

}

}

}

catch (RemoteException e) {

System.err.println(e.toString());

System.err.println(PM_NOT_RUNNING_ERR);

}

}

//包安装观察者

class

PackageInstallObserver extends IPackageInstallObserver.Stub

{

boolean finished;

int result;

public void packageInstalled(String name, int status)

{

synchronized( this) {

finished = true;

result = status;

notifyAll();

}

}

}

PackageManagerService与DefaultContainerService

DefaultContainerService源码位于frameworks/base/packages/DefaultContainerService,生成的DefaultContainerService.apk在system/app/目录下,是一个系统级别的应用,不

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值