【AndroidFramewok】AndroidManifest中Original Package标签

<original-package android:name="com.android.packageinstaller" />

最近看到系统app的AndroidManifest中有个标签,不是很懂什么含义。

original-package 作用

通过源码搜索original-package,在源码中找到两处。

  frameworks/base/core/java/android/content/pm/PackageParser.java:1274   
  frameworks/base/services/java/com/android/server/BackupManagerService.java:3918:

我们先来看PackageParser.java类

    else if (tagName.equals("original-package")) {
                    sa = res.obtainAttributes(attrs,
                            com.android.internal.R.styleable.AndroidManifestOriginalPackage);

            String orig =sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestOriginalPackage_name, 0);
            if (!pkg.packageName.equals(orig)) {
                if (pkg.mOriginalPackages == null) {
                    pkg.mOriginalPackages = new ArrayList<String>();
                    pkg.mRealPackage = pkg.packageName;
                }
                pkg.mOriginalPackages.add(orig);
            }

            sa.recycle();

            XmlUtils.skipCurrentTag(parser);
            
        } 
            String orig =sa.getNonConfigurationString(
                    com.android.internal.R.styleable.AndroidManifestOriginalPackage_name, 0);
            if (!pkg.packageName.equals(orig)) {
                if (pkg.mOriginalPackages == null) {
                    pkg.mOriginalPackages = new ArrayList<String>();
                    pkg.mRealPackage = pkg.packageName;
                }
                pkg.mOriginalPackages.add(orig);
            }

            sa.recycle();

            XmlUtils.skipCurrentTag(parser);
            
        } 

AndroidManifestOriginalPackage 的定义,在 attrs_manifest.xml 文件中:

     <p>This appears as a child tag of the root
     {@link #AndroidManifest manifest} tag. -->
<declare-styleable name="AndroidManifestOriginalPackage" parent="AndroidManifest">
    <attr name="name" />
</declare-styleable>

google翻译一下

用于声明此程序包所在的原始程序包名称的私有标记基于。 仅用于系统映像中安装的软件包。 如果给定的,不同于实际的包名和给定的原始软件包以前安装在设备上但是新的一个不是,那么旧的数据将被重命名为对于新应用。

官方的解释很清楚了:之前安装的应用是系统应用,并且包名不同,之前应用的数据就会以新安装应用的名字保留下来。

上面 parsePackage() 方法中的 mOriginalPackages,查源码可知对 mOriginalPackages 的其余处理只在 PackageManagerServerice 中了。我们来看PMS的scanPackageLI方法

    if (pkg.mOriginalPackages != null) {
            // This package may need to be renamed to a previously
            // installed name.  Let's check on that...
            final String renamed = mSettings.mRenamedPackages.get(pkg.mRealPackage);
            if (pkg.mOriginalPackages.contains(renamed)) {
                // This package had originally been installed as the
                // original name, and we have already taken care of
                // transitioning to the new one.  Just update the new
                // one to continue using the old name.
                realName = pkg.mRealPackage;
                if (!pkg.packageName.equals(renamed)) {
                    // Callers into this function may have already taken
                    // care of renaming the package; only do it here if
                    // it is not already done.
                    pkg.setPackageName(renamed);
                }
                
            } else {
                for (int i=pkg.mOriginalPackages.size()-1; i>=0; i--) {
                    if ((origPackage = mSettings.peekPackageLPr(
                            pkg.mOriginalPackages.get(i))) != null) {
                        // We do have the package already installed under its
                        // original name...  should we use it?
                        if (!verifyPackageUpdateLPr(origPackage, pkg)) {
                            // New package is not compatible with original.
                            origPackage = null;
                            continue;
                        } else if (origPackage.sharedUser != null) {
                            // Make sure uid is compatible between packages.
                            if (!origPackage.sharedUser.name.equals(pkg.mSharedUserId)) {
                                Slog.w(TAG, "Unable to migrate data from " + origPackage.name
                                        + " to " + pkg.packageName + ": old uid "
                                        + origPackage.sharedUser.name
                                        + " differs from " + pkg.mSharedUserId);
                                origPackage = null;
                                continue;
                            }
                        } else {
                            if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
                                    + pkg.packageName + " to old name " + origPackage.name);
                        }
                        break;
                    }
                }
            }
        }

我们看到有英文提示,当mOriginalPackages!=null并与原来名字一样的时候 ,会赋值realName = pkg.mRealPackage;
然后调用Settings.java(frameworks\base\services\java\com\android\server\pm)的getPackageLPw(),看下这个方法

        if (origPackage != null) {
            // We are consuming the data from an existing package.
            p = new PackageSetting(origPackage.name, name, codePath, resourcePath,
                    nativeLibraryPathString, vc, pkgFlags);
            if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
                    + name + " is adopting original package " + origPackage.name);
            // Note that we will retain the new package's signature so
            // that we can keep its data.
            PackageSignatures s = p.signatures;
            p.copyFrom(origPackage);
            p.signatures = s;
            p.sharedUser = origPackage.sharedUser;
            p.appId = origPackage.appId;
            p.origPackage = origPackage;
            mRenamedPackages.put(name, origPackage.name);
            name = origPackage.name;
            // Update new package state.
            p.setTimeStamp(codePath.lastModified());
        } else {
            p = new PackageSetting(name, realName, codePath, resourcePath,
                    nativeLibraryPathString, vc, pkgFlags);
            p.setTimeStamp(codePath.lastModified());
            p.sharedUser = sharedUser;
            // If this is not a system app, it starts out stopped.
            if ((pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
                if (DEBUG_STOPPED) {
                    RuntimeException e = new RuntimeException("here");
                    e.fillInStackTrace();
                    Slog.i(PackageManagerService.TAG, "Stopping package " + name, e);
                }
                List<UserInfo> users = getAllUsers();
                if (users != null && allowInstall) {
                    for (UserInfo user : users) {
                        // By default we consider this app to be installed
                        // for the user if no user has been specified (which
                        // means to leave it at its original value, and the
                        // original default value is true), or we are being
                        // asked to install for all users, or this is the
                        // user we are installing for.
                        final boolean installed = installUser == null
                                || installUser.getIdentifier() == UserHandle.USER_ALL
                                || installUser.getIdentifier() == user.id;
                        p.setUserState(user.id, COMPONENT_ENABLED_STATE_DEFAULT,
                                installed,
                                true, // stopped,
                                true, // notLaunched
                                false, // blocked
                                null, null, null);
                        writePackageRestrictionsLPr(user.id);
                    }
                }
            }   

使用现有应用的数据,实现数据共享。
我们总算找到这个标签的作用了。恭喜!

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

推荐阅读更多精彩内容

  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 12,715评论 2 59
  • APK安装流程系列文章整体内容如下: APK安装流程详解0——前言APK安装流程详解1——有关"安装ing"的实体...
    隔壁老李头阅读 14,205评论 15 59
  • 每个人从呱呱坠地开始,在生命的旅程中,便充满神奇的际遇,也会面对许许多多生命中的第一次。 第一次也许是惊奇地,也许...
    莫晓烟雨阅读 562评论 2 6
  • “没有人会保护你一世”,小时聂雨说的话又在耳边响起。在他说出这句话的时候,我就知道总有一天我会离开他们,离开...
    无槡阅读 225评论 0 0
  • 我性格里有个很大的缺点就是做事不顾后果。然而也正因为这样的性格,正向阐述是做决定从不拖沓。雷厉风行。元气满分。越挫...
    给我一只猴子阅读 246评论 0 2