"versionCodeMajor是什么?它和versionCode有什么区别?"

16
我刚发现在Android Pie中PackageInfo.versionCode已被弃用,他们建议使用PackageInfo.getLongVersionCode()。这个新方法的JavaDoc是:
返回versionCodeversionCodeMajor合并为一个长整型值。versionCodeMajor放在高32位。
但是什么是versionCodeMajor?我该如何使用它?versionCodeMajor和旧版versionCode之间有什么区别?
它的文档几乎没有提到任何东西:
内部主要版本代码。这本质上是基本版本代码的附加高位;除了更高的数字表示更近期以外,它没有其他意义。这不是通常由R.attr.versionName提供给用户的版本号。

2
我认为这很容易理解。他们将版本代码从“int”扩展到“long”。以向后兼容的方式实现这一点的方法是将两个“int”打包到该“long”中,其中低“int”是旧版本代码,高“int”默认为零。我不认为大多数人需要这些内容,但显然谷歌的某个产品团队在其版本控制实践中不明智,正在用尽数字。 - j__m
也许他们从旧的错误乐观主义中学到了教训,认为640 KB的RAM足够了,决定采取安全措施,不假设40亿个版本总是足够的。 :-) - Edward Brey
2个回答

15

到目前为止,我发现在Android Studio 3.2.1中设置versionCodeMajor的唯一方法是通过AndroidManifest.xml并禁用InstantRun

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:versionCodeMajor="8" [...]

因为在 build.gradle 文件中设置它,你会得到

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.xxx.myapplicationp"
        minSdkVersion 'P'
        targetSdkVersion 'P'
        versionCode 127
        //versionCodeMajor 8
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

找不到方法 versionCodeMajor() 的参数。

所以,在AndroidManifest.xml文件中设置你选择的主版本号码,并禁用InstantRun后,可以通过以下方式获取它:

static long getAppVersionCode(Context context) throws PackageManager.NameNotFoundException {
        PackageInfo pinfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
        long returnValue = Long.MAX_VALUE;
        //if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P
                && !"P".equals(Build.VERSION.CODENAME) /* This 'cause the dev preview */) {
            returnValue = pinfo.versionCode;
        } else {
            returnValue = pinfo.getLongVersionCode();
            Log.d("AAA", "Full long value: " + returnValue);
            Log.d("AAA", "Major Version Code (your chosen one) " + (returnValue >> 32)); // 8 in this scenario
            Log.d("AAA", "Version Code (your chosen one) " + (int)(returnValue & 0x00000000ffffffff)); // 127 in this scenario
        }
        return returnValue;
    }

您还可以使用PackageInfoCompat,如下所示:

static long getAppVersionCode(Context context) throws PackageManager.NameNotFoundException {
        PackageInfo pinfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
        long returnValue = Long.MAX_VALUE;
        returnValue = PackageInfoCompat.getLongVersionCode(pinfo);
        if (BuildConfig.DEBUG) {
            int majorCode = (int)(returnValue >> 32);
            int versionCode = (int)(returnValue & 0x00000000ffffffff); // or simply returnValue

            Log.d("AAA", "Full long value: " + returnValue);
            Log.d("AAA", "Major Version Code (your chosen one) " + majorCode); // 8 in this scenario
            Log.d("AAA", "Version Code (your chosen one) " + versionCode); // 127 in this scenario
        }
        return returnValue;
    }

这应该回答了如何使用它或一种方法。

至于何时和为什么使用它...我想这取决于你...正如你指出的那样,文档没有告诉你为什么应该使用它。文档说你应该向用户展示已知的versionNumber版本。

我猜他们添加了一些位到versionCode中,因为他们需要一个更大的数字来进行版本控制^^'

话虽如此,如果您没有在AndroidManifest.xml或build.gradle文件中设置versionCodeMajor(在处理时),或将其设置为0,则此值与旧的已弃用的versionNumber字段相同。


@DanielWilson 我的回答还是安卓做了什么?^^' - shadowsheep
1
安卓做了什么 :) - Daniel Wilson

0

获取版本名称和版本代码的另一种方法是通过BuildConfig

BuildConfig.VERSION_CODE
BuildConfig.VERSION_NAME

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接