PM命令分析

1, PM命令
命令格式:

pm <command>

 

命令列表:

命令

功能

實現方法

list packages

列舉app包信息

PMS.getInstalledPackages

install [options] <PATH>

安裝應用

PMS.installPackageAsUser

uninstall [options]<package>

卸載應用

IPackageInstaller.uninstall

enable <包名或組件名>

enable

PMS.setEnabledSetting

disable <包名或組件名>

disable

PMS.setEnabledSetting

hide <package>

隱藏應用

PMS.setApplicationHiddenSettingAsUser

unhide <package>

顯示應用

PMS.setApplicationHiddenSettingAsUser

get-install-location

獲取安裝位置

PMS.getInstallLocation

set-install-location

設置安裝位置

PMS.setInstallLocation

path <package>

查看App路徑

PMS.getPackageInfo

clear <package>

清空App數據

AMS.clearApplicationUserData

get-max-users

最大用戶數

UserManager.getMaxSupportedUsers

force-dex-opt <package>

dex優化

PMS.forceDexOpt

dump <package>

dump信息

AM.dumpPackageStateStatic

trim-caches <目標size>

緊縮cache目標大小

PMS.freeStorageAndNotify

 

2, 詳細參數
2.1 list packages
查看所有的package

list packages [options] <FILTER>

其中[options]參數:

-f: 顯示包名所關聯的文件;

-d: 只顯示disabled包名;

-e: 只顯示enabled包名;

-s: 只顯示系統包名;

-3: 只顯示第3方應用的包名;

-i: 包名所相應的installer;

-u: 包含uninstalled包名.

規律: disabled + enabled = 總應用個數; 系統 + 第三方 = 總應用個數。

比如:查看第3方應用:

pm list packages -3

又比如,查看已經被禁用的包名。(國內的廠商一般把google的服務禁用了)

pm list packages -d

<FILTER>參數:

當FILTER爲不爲空時,則只會輸出包名帶有FILTER字段的應用;當FILTER爲空時,則默認顯示所有滿足條件的應用。

比如,查看包名帶google字段的包名

pm list packages google

2.2 pm install
安裝應用

pm install [options] <PATH>

其中[options]參數:

-r: 覆蓋安裝已存在Apk,並保持原有數據;

-d: 運行安裝低版本Apk;

-t: 運行安裝測試Apk

-i : 指定Apk的安裝器;

-s: 安裝apk到共享快存儲,比如sdcard;

-f: 安裝apk到內部系統內存;

-l: 安裝過程,持有轉發鎖

-g: 准許Apk manifest中的所有權限;

<PATH>參數:

該參數是必須的,是指需要安裝的apk所在的路徑。

2.3 其他參數
pm list users //查看當前手機用戶

pm list libraries //查看當前設備所支持的庫

pm list features //查看系統所有的features

pm list instrumentation //所有測試包的信息

pm list permission-groups //查看所有的權限組

pm list permissions [options]<group> 查看權限

   -g: 以組形式組織;

   -f: 打印所有信息;

   -s: 簡要信息;

   -d: 只列舉危險權限;

   -u: 只列舉用戶可見的權限。

 

3, 詳細流程
所有adb命令的pm方法最後都會通過Pm.java執行,然後大都會調用PMS的方法完成,至於android系統中的adb原理在此就不論述了。

   PM的main方法如下,

public static void main(String[] args) {
        int exitCode = 1;
        try {
            exitCode = new Pm().run(args);
        } catch (Exception e) {
            Log.e(TAG, "Error", e);
            System.err.println("Error: " + e);
            if (e instanceof RemoteException) {
                System.err.println(PM_NOT_RUNNING_ERR);
            }
        }
        System.exit(exitCode);
    }
直接調用run方法,

public int run(String[] args) throws IOException, RemoteException {
        boolean validCommand = false;
        if (args.length < 1) {
            return showUsage();
        }
        mUm = IUserManager.Stub.asInterface(ServiceManager.getService("user"));
        mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
         // 獲取PMS對象
        if (mPm == null) {
            System.err.println(PM_NOT_RUNNING_ERR);
            return 1;
        }
        mInstaller = mPm.getPackageInstaller();
        mArgs = args;
        String op = args[0]; // 獲取指令
        mNextArg = 1;
        •••
        if ("install".equals(op)) {
            return runInstall();
        }
•••
不同的指令分別對應不同的方法,例如,install命令會調用runInstall方法, runInstall方法如下,

private int runInstall() {
        int installFlags = 0;
        int userId = UserHandle.USER_ALL;
        String installerPackageName = null;
 
        String opt;
 
        String originatingUriString = null;
        String referrer = null;
        String abi = null;
 
        while ((opt=nextOption()) != null) {
            if (opt.equals("-l")) {
                installFlags |= PackageManager.INSTALL_FORWARD_LOCK;
            } else if (opt.equals("-r")) {
                installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
            } else if (opt.equals("-i")) {
          •••
LocalPackageInstallObserver obs = new LocalPackageInstallObserver();
        try {
            VerificationParams verificationParams = new VerificationParams(verificationURI,
                    originatingURI, referrerURI, VerificationParams.NO_UID, null);
 
            mPm.installPackageAsUser(apkFilePath, obs.getBinder(), installFlags,
                    installerPackageName, verificationParams, abi, userId);
 
            synchronized (obs) {
                while (!obs.finished) {
                    try {
                        obs.wait();
                    } catch (InterruptedException e) {
                    }
                }
                if (obs.result == PackageManager.INSTALL_SUCCEEDED) {
                    System.out.println("Success");
                    return 0;
                } else {
                    System.err.println("Failure ["
                            + installFailureToString(obs)
                            + "]");
                    return 1;
                }
            }
        } catch (RemoteException e) {
            System.err.println(e.toString());
            System.err.println(PM_NOT_RUNNING_ERR);
            return 1;
        }
    }
無論是哪一個install命令,最後都是調用PMS的installPackageAsUser方法進行apk的安裝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章