获取版本代码时没有虚方法 getLongVersionCode()J

No virtual method getLongVersionCode()J when getting version code

根据 google 建议,我正在使用 getLongVersionCode 来获取这样的版本代码:

private long getCurrentCode() {
    try {
        return context.getPackageManager()
                .getPackageInfo(context.getPackageName(), 0).getLongVersionCode();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return -1;
}

但是当我 运行 我的应用程序时,我的应用程序强制关闭并且出现此错误:

Process: com.xxxxx.debug, PID: 25754
    java.lang.NoSuchMethodError: No virtual method getLongVersionCode()J in class Landroid/content/pm/PackageInfo; or its super classes (declaration of 'android.content.pm.PackageInfo' appears in /system/framework/framework.jar)
        at com.xxxxx.common.ApplicationUpdateTask.getCurrentCode(ApplicationUpdateTask.java:329)
        at com.xxxxx.common.ApplicationUpdateTask.<init>(ApplicationUpdateTask.java:84)

所以我决定使用:

String versionName = BuildConfig.VERSION_NAME;

但是现在这个表扬return-1!!!!!

这是我的 gradle 配置:

compileSdkVersion 28
    buildToolsVersion '28.0.3'
    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 66
        versionName '2.0.66'
        applicationId 'com.xxxxxx.yyyyy'
        multiDexEnabled true
    }

方法long getLongVersionCode()在版本28中添加到Android;见 javadoc

它显然存在于您正在编译的 APIs 中,否则您会遇到编译错误。

但异常表明它在运行时不存在,因此您一定是 运行 在较旧的平台上。

我不知道你说你用这个是什么意思:

String versionName = BuildConfig.VERSION_NAME;

版本名称和代码是不同的东西。也许你用过BuildConfig.VERSION_CODE

我不知道你的意思:

but now this commend return -1 !!!!!

我的猜测是您使用版本名称或代码属性的方式有问题。但这只是一个猜测。您还没有向我们展示代码。


另一件需要注意的事情是,在 API 版本 28 之前,您可以使用 PackageInfo.versionCode 属性 (javadoc)。这在 API 版本 28 中已弃用。因此应该可以使用反射来调用 getLongVersionCode() 方法(如果可用),然后回退到使用反射来访问 versionCode 属性。 (或在运行时测试 Build.VERSION.SDK_INT 的值以找出平台支持的 API 版本。)

或者您可以将应用程序支持的最低 Android 版本设置为 28。

注意这里的人。虽然这说它是在 28 中添加的,但我可以肯定地说它在 Android 8.1 中不起作用。相同的运行时错误。在尝试使用 getLongVersionCode() 之前更改我的代码以检查 Android.os.Build.VERSION_SDK_INT >= Build.VERSION_CODES.P 避免了错误。

我建议您使用 PackageInfoCompat:

PackageInfoCompat.getLongVersionCode();

它会自动检查大于28的sdk版本和returns适当的versionCode或LongVersionCode。它包含在 androidx.