Framework基础:包管理之system/priv-app下的子目录规则

Paste_Image.png

今天忙的要命。今天发年终奖了,第一次拿年终奖,感觉比想象中多一点。今天主要在同步一堆的代码,现在改一个代码可麻烦了,要同步到很多个平台,高通mtk平台全部同步一篇,真是同步到手软,不知道其他公司是不是这样做的,小米他们几十台手机,项目不知道是怎么管理的。说回正题,今天主要处理一个运营商的一个要求,运营商要求把他的app内置到system/priv-app,但只在运营商版本把这个apk安装,手机有一个标志位区分运营商版本和普通版本,如何处理呢?

将运营商apk放置到system/priv-app的子目录是否可以呢?

在system/priv-app新建一个子目录Carrier,然后把该运营商的所有apk放置到这个这个目录。有个子目录,就可以便于区分运营商的apk和系统的apk了。主要是比较好看,如果直接把apk都扔到system/priv-app,那system/priv-app下的apk就太多了,看花眼了。放置完就是下面这样子。

内置apk.png

但实践发现,这样子apk并不能安装。

为什么呢?还是从源码出发,看看安装的流程。
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
在PackageManagerService的构造函数中,会去扫描system/priv-app 目录

            // Collected privileged system packages.
            final File privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app");
            scanDirLI(privilegedAppDir, PackageParser.PARSE_IS_SYSTEM
                    | PackageParser.PARSE_IS_SYSTEM_DIR
                    | PackageParser.PARSE_IS_PRIVILEGED, scanFlags, 0);

进入scanDirLI

    private void scanDirLI(File dir, int parseFlags, int scanFlags, long currentTime) {
        final File[] files = dir.listFiles();
        for (File file : files) {
               //扫到运营商目录是,file的值是System/priv-app/Carrier
                scanPackageLI(file, parseFlags | PackageParser.PARSE_MUST_BE_APK,
        }
    }

进入scanPackageLI

    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
            long currentTime, UserHandle user) throws PackageManagerException {
        .................
       PackageParser pp = new PackageParser();
       final PackageParser.Package pkg;
        try {
            //解释System/priv-app/Carrier文件夹
            pkg = pp.parsePackage(scanFile, parseFlags);
        } catch (PackageParserException e) {
            throw PackageManagerException.from(e);
        }
        ................
    }

PackageParser用于解释文件夹下的apk文件,把解释结果放在PackageParser.Package中。
看看PackageParser的parsePackage方法

    public Package parsePackage(File packageFile, int flags) throws PackageParserException {
        if (packageFile.isDirectory()) {   //System/priv-app/Carrier满足这个条件
            return parseClusterPackage(packageFile, flags);
        } else {
            return parseMonolithicPackage(packageFile, flags);
        }
    }

    private Package parseClusterPackage(File packageDir, int flags) throws PackageParserException {
       ......................
        final PackageLite lite = parseClusterPackageLite(packageDir, 0);
        .......................
    }

    private static PackageLite parseClusterPackageLite(File packageDir, int flags)
            throws PackageParserException {
        ..............
        final File[] files = packageDir.listFiles();

        final ArrayMap<String, ApkLite> apks = new ArrayMap<>();
        for (File file : files) {
            //列出System/priv-app/Carrier所有apk,包括hehe.apk,haha.apk
            if (isApkFile(file)) {
                final ApkLite lite = parseApkLite(file, flags);

                // Assert that all package names and version codes are
                // consistent with the first one we encounter.
                if (packageName == null) {
                    packageName = lite.packageName;  //
                    versionCode = lite.versionCode;
                } else {
                    //关键点在这里,如果两个apk不一样,就会抛出异常。说明子目录只能有一个apk
                    if (!packageName.equals(lite.packageName)) {
                        throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
                                "Inconsistent package " + lite.packageName + " in " + file
                                + "; expected " + packageName);
                    }
                    if (versionCode != lite.versionCode) {
                        throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
                                "Inconsistent version " + lite.versionCode + " in " + file
                                + "; expected " + versionCode);
                    }
                }

                // Assert that each split is defined only once
                if (apks.put(lite.splitName, lite) != null) {
                    throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
                            "Split name " + lite.splitName
                            + " defined more than once; most recent was " + file);
                }
            }
        }
        ...................
    }

看看上面的注释,pms会判断system/priv-app子目录的apk包名,要保证子目录只有一个apk,否则不能安装。因为System/priv-app/Carrier有两个apk,hehe.apk和haha.apk,所以安装失败!!分析完毕。看看下面正常的apk都是长这样的,子目录只有一个apk

一个apk.png

总结

system/priv-app下的子目录内只能有一个apk,否则会安装失败。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容