【问题标题】:APK completely shadowed with multiple ABI APKsAPK 完全被多个 ABI APK 所掩盖
【发布时间】:2019-05-21 20:27:00
【问题描述】:

更新:尝试将“v7a”ABI 版本代码降低到前缀 4(低于 5,即“v8”),但没有任何运气

目前我的应用程序处于 Alpha 阶段。每个 APK 都是通过相同的 ABI 拆分和每个 ABI(包括代码)的相同版本乘法生成的,生成到“armeabi-v7a”和“arm64-v8a”。尽管到目前为止我只上传了“v8a”APK。现在,当我尝试上传“v7a”时,我从 google play 控制台收到以下错误:

问题: 此 APK 不会提供给任何用户,因为它完全被一个或多个具有更高版本代码的 APK 所掩盖。 解决: 从您的版本中删除此 APK,或查看您在此版本中包含的 APK 的定位和版本代码。

android {
compileSdkVersion 26

buildToolsVersion '28.0.3'

defaultConfig {
    multiDexEnabled true
    minSdkVersion 21
    versionCode 28
    versionName "1.36"
    targetSdkVersion 26
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    if (nativeBuildSystem == 'cmake') {
        externalNativeBuild {
            cmake {
                arguments '-DANDROID_TOOLCHAIN=gcc', '-DANDROID_STL=gnustl_static'
            }
        }
    }

}

if (nativeBuildSystem == 'cmake') {
    externalNativeBuild {
        cmake {
            path './jni/CMakeLists.txt'
        }
    }
}

// special for TFLite without it we will get an error when trying
// to use 'detect.tflite' assets file
aaptOptions {
    noCompress "tflite"
}

splits {
    abi {
        enable true
        reset()
        include "armeabi-v7a", "arm64-v8a"
        universalApk false
    }
}


lintOptions {
    abortOnError false
}

sourceSets {
    main {
        if (nativeBuildSystem == 'bazel' || nativeBuildSystem == 'makefile') {
            // TensorFlow Java API sources.
            java {
                srcDir '../../java/src/main/java'
                exclude '**/examples/**'
            }

            // Android TensorFlow wrappers, etc.
            java {
                srcDir '../../contrib/android/java'
            }
        }
        // Android demo app sources.
        java {
            srcDir 'src'
        }

        manifest.srcFile 'AndroidManifest.xml'
        resources.srcDirs = ['src']
        aidl.srcDirs = ['src']
        renderscript.srcDirs = ['src']
        res.srcDirs = ['res']
        assets.srcDirs = [project.ext.ASSET_DIR]
    }

    androidTest {
        java.srcDirs = ['src/androidTest/java', 'src']
    }

    debug.setRoot('build-types/debug')
    release.setRoot('build-types/release')
}

}

版本代码分离:

ext.versionCodes = ['arm64-v8a': 5, 'armeabi-v7a': 6]

import com.android.build.OutputFile


android.applicationVariants.all { variant ->
// assign different version code for each output
    variant.outputs.each { output ->

        def abiFilter = output.getFilter(OutputFile.ABI)
        def abiMultiplier = 0
        if (abiFilter != null) {
            abiMultiplier = (int) project.ext.versionCodes.get(abiFilter)
        }

        output.versionCodeOverride = (int) abiMultiplier * 1000 + (int) android.defaultConfig.versionCode
    }
}

还附上了游戏控制台的屏幕截图。似乎“v7a”APK 的版本正在遮盖“v8”,好像播放控制台似乎没有区分它们之间的架构。这一假设也得到了以下事实的支持:每个 APK 的描述都说 APK 支持这两个平台。

【问题讨论】:

  • 运气好,我也面临同样的问题?

标签: android android-gradle-plugin apk abi


【解决方案1】:

arm64-v8a APK 的 versionCode 应该高于 armeavi-v7a APK 的 versionCode。

为了确定提供哪个 APK,Play 会选择与给定设备兼容的最高 versionCode。因为所有支持 64 位的设备 (arm64-v8a) 也支持 32 位 (armeabi-v7a),如果您将 32 位 APK 放入更高版本的代码,它也将匹配 64 位设备,因此将提供一个而不是 64 位的。这就是 Play 告诉您 arm64-v8a 被遮蔽的原因。

希望对您有所帮助。

【讨论】:

  • 对于 ARM 使用 7 (th generation) 和对于 ARM64 使用 8 (th generation) 将被分配 1:1 - 它应该满足规定的要求。 ARM64 将只运行 32 位程序集,当使用目录 armeabi 时 - 在 armeabi-v7aarm64-v8a 中找不到程序集。
  • @Pierre 我很确定我尝试了两种方法,但如果可行,我会重新上传和更新
  • 试过你的建议,现在我正在屏蔽“v7a”APK(ov versionCode 40..)。所以还是没有运气
  • 哦,我错过了你的截图中的一件事。实际上,您的两个 APK 似乎都包含两个 ABI。这也解释了阴影。可以打开APK(解压)验证吗?
  • 是的,这也是我的预感。感谢您的关注!我已经在两个 APK 中添加了两个 ABI 架构 OpenCV 库,我正在添加一个详细的答案
【解决方案2】:

正如 Pierre 建议的那样,每个 APK(v7a、v8)都包含两个 ABI。但你问怎么会这样?

由于 JavaCV(OpenCV 库)两个 ABI 在一个模块中的 Gradle 依赖关系:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support:recyclerview-v7:26.1.0'

    api (group: 'org.bytedeco', name: 'javacv', version: '1.4.3', {
        exclude group: 'org.bytedeco.javacpp-presets', module: 'flandmark'
        exclude group: 'org.bytedeco.javacpp-presets', module: 'flycapture'
        exclude group: 'org.bytedeco.javacpp-presets', module: 'leptonica'
        exclude group: 'org.bytedeco.javacpp-presets', module: 'libdc1394'
        exclude group: 'org.bytedeco.javacpp-presets', module: 'libfreenect2'
        exclude group: 'org.bytedeco.javacpp-presets', module: 'libfreenect'
        exclude group: 'org.bytedeco.javacpp-presets', module: 'librealsense'
        exclude group: 'org.bytedeco.javacpp-presets', module: 'tesseract'
        exclude group: 'org.bytedeco.javacpp-presets', module: 'videoinput'
        exclude group: 'org.bytedeco.javacpp-presets', module: 'artoolkitplus'
    })

    // add the libraries you need depending on your mobile phone - if you get an exception or
    // "... class not found", or "didn't load library ...", try replace android-arm64 with android-arm, or with android-x86
    implementation group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.4.3-1.4.3', classifier: 'android-arm'
    implementation group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.4.3-1.4.3', classifier: 'android-arm64'
}

我注释掉了implementation group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.4.3-1.4.3', classifier: 'android-arm64',重新上传并成功了。 arm64 支持 arm,但反之则不行。

【讨论】:

  • 添加依赖应该不是问题。但是,如果您想在 Gradle (developer.android.com/studio/build/configure-apk-splits) 上正确生成多 apk,则应使用启用 ABI 拆分的 split 块。一个更简单的选择是发布一个 Android App Bundle 而不是多个 APK,Play 将为您完成所有这些艰苦的工作:g.co/androidappbundle
  • @Pierre 我确实使用了拆分块。但是我附加的依赖项有两种不同的架构,我认为构建系统不会自动拆分它们(我的取消注释证明了这一点),除非我手动将 jar 放在正确的 jniLibs 文件夹中。我希望 AppBundle 可以工作,但由于这些相同的 JavaCV 库,我得到了一个不同的错误
  • 构建系统应该拆分它们,是的。这个库的打包方式可能有问题。也许他们包装成罐子而不是 aar。我试试看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-26
  • 1970-01-01
  • 2021-11-24
  • 2017-07-13
相关资源
最近更新 更多