Android pm 命令

本文深入探讨了Android系统中`pm`命令的实现细节。从Android 6.0到9.0,`pm`命令从一个shell脚本转变为通过`cmd`执行。在Android 6.0中,`pm`直接调用`Pm.java`处理不同操作,如`list`、`install`等。而在Android 9.0中,`pm`通过`cmd`间接调用`PackageManagerService`来执行相应功能。整个过程涉及`IServiceManager`和`IPackageManager`的交互,揭示了Android系统管理应用程序的核心流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

经常在使用中的am & pm 命令,现在来看看里面到底是什么东西,以pm 为例:

在Android 6.0 中

cat /system/bin/pm

# shell.
base=/system
export CLASSPATH=$base/framework/pm.jar
exec app_process $base/bin com.android.commands.pm.Pm "$@"

首先我们需要知道/system/bin/pm是一个可执行的shell 文件
在Android6.0中,这个shell 脚本文件实际上执行的是源文件是
frameworks/base/cmds/pm/src/com/android/commands/pm/Pm.java
Pm->main->new Pm().run(args)->

public int run(String[] args) throws IOException, RemoteException {
        ......
        这里省略了部分代码,只看关键部分
        ......
        if ("list".equals(op)) {
            return runList();
        }

        if ("path".equals(op)) {
            return runPath();
        }
        if ("dump".equals(op)) {
            return runDump();
        }

        if ("install".equals(op)) {
            return runInstall();
        }
    
        if ("uninstall".equals(op)) {
            return runUninstall();
        }

        if ("clear".equals(op)) {
            return runClear();
        }
        ...
        这里省略了部分代码,只看关键部分
        ......
    }

看到这里逻辑就很清楚了,根据参数做不同的处理。最后通过IPackageManager mPm = IPackageManager.Stub.asInterface(ServiceManager.getService(“package”)); 调用到PackageManagerService 里面去。

在Android 9.0 中

cat /system/bin/pm

#!/system/bin/sh
cmd package "$@"

cmd 是什么呢,
which cmd 查看一下:

 /system/bin/cmd

cmd 是一个二进制文件
frameworks/native/cmds/cmd/cmd.cpp

int main(int argc, char* const argv[])
{
	....
    sp<IServiceManager> sm = defaultServiceManager();
    ...
    sp<IBinder> service = sm->checkService(cmd);
 	...
    status_t err = IBinder::shellCommand(service, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, 
    ...
}

关系图

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

@Override
    public void onShellCommand() {
         (new PackageManagerShellCommand(this)).exec( 
                this, in, out, err, args, callback, resultReceiver);
    }

frameworks/base/services/core/java/com/android/server/pm/PackageManagerShellCommand.java

public int onCommand(String cmd) {
   		...
        try {
            switch(cmd) {
                case "path":
                    return runPath();
                case "dump":
                    return runDump();
                case "list":
                    return runList();
           
                case "uninstall":
                    return runUninstall();
                case "clear":
                    return runClear();
                case "enable":
                    return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
                case "disable":
                    return runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
                case "disable-user":
                    return runSetEnabledSetting(
                            PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
          
                    return uninstallSystemUpdates();
                ...
            }
        } catch (RemoteException e) {
            pw.println("Remote exception: " + e);
        }
        return -1;
    }

看到这里整体的脉络应该是比较清晰了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值