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

Posted

技术标签:

【中文标题】什么是 versionCodeMajor?和 versionCode 有什么区别?【英文标题】:What is versionCodeMajor? And what is the difference with versionCode? 【发布时间】:2019-03-08 20:56:57 【问题描述】:

我刚刚发现 PackageInfo.versionCodeandroid Pie 中已被弃用。他们指出您改用PackageInfo.getLongVersionCode()。这个新方法的JavaDoc是:

返回 versionCodeversionCodeMajor 组合在一起作为单个 long 值。 versionCodeMajor 放在高 32 位。

但是versionCodeMajor 是什么?我必须如何使用它? versionCodeMajor和老的versionCode有什么区别?

它的文档几乎什么也没说:

内部主要版本代码。这本质上是基本版本代码的附加高位;它没有其他意义,只是更高的数字是最近的。这不是通常向用户显示的版本号,通常与 R.attr.versionName 一起提供。

【问题讨论】:

我认为这是不言自明的。他们将版本代码从int 扩展为long。以向后兼容的方式做到这一点的方法是将两个ints 打包到long 中,其中低int 是旧版本代码,高int 默认为零。我不认为大多数人都需要这些,但显然 Google 的一些产品团队在他们的版本控制实践中是不明智的,并且数量已经不多了。 也许他们从过去的错误乐观中学到了 640 KB 将是“大量” RAM,并决定谨慎行事,而不是假设 40 亿个版本就足够了。 :-) 【参考方案1】:

到目前为止,我发现使用 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;
    

这应该回答如何使用它或如何使用它。

何时以及为什么使用它...我想这取决于您...正如您所指出的,文档没有告诉您为什么应该使用它。什么文档说你应该只向你的用户展示众所周知的版本号。

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

也就是说,如果您没有在AndroidManifest.xmlbuild.gradle 文件中设置versionCodeMajor(当它将处理它时),或者您将其设置为0,那么此值与旧的 versionNumber 已弃用的字段。

【讨论】:

@DanielWilson 我的回答还是 android 做了什么? ^^' Android 做了什么 :)

以上是关于什么是 versionCodeMajor?和 versionCode 有什么区别?的主要内容,如果未能解决你的问题,请参考以下文章

001入门级的超融合私有云开源解决方案Proxmox VE之规划部署

001入门级的超融合私有云开源解决方案Proxmox VE之规划部署

Love2d从青铜到王者第四篇:Love2d之LÖVE与移动矩形

c_cpp 替换+ ve和-ve no.s的数组

proxmox VE 版本5.X支持警告

proxmox VE 版本5.X支持警告