如何使用 Gradle 实验性插件对 64 位 Android APK 进行协同设计?

How can I codesign a 64-bit Android APK using the Gradle Experimental Plugin?

我正在使用支持 Android 的 C++ 框架 Open Frameworks 开发 Android 应用程序。它的 Android 项目使用 Gradle 实验性插件来允许 C++。 我已经能够得到这些来构建 未签名 APK,运行 很好(使用 Android Studio 2.3.2 、3.0、3.5 或 3.5.1,实验性 Gradle 插件 0.9.3,以及 Gradle 分发版 3.3.0)。 但现在我需要对它们进行代码签名,并将 64 位版本 包含到 post 到 Android 商店。

Gradle 实验性插件始终需要针对其每个版本的特定单一版本的 Gradle 分发。 current doc page for the plugin 说我们可以 "keep using experimental plugin 0.11.0 with Android Studio 3.0 or later",但我似乎被 Android Studio 3.5 和 3.5.1 中的上述内容阻止了代码签名。

当我尝试将最新版本的 Android Studio(版本 3.5 或 3.5.1)用于 "Generate Signed APK" 时,我被 "Gradle version 4.1 is required." 阻止了。

当我尝试将旧版本的 Android Studio(版本 2.3.2 或 3.0)用于 "Generate Signed APK" 时,我可以构建 32 位代码签名的 APK,但我不知道如何构建 64 位 APK。 我找到的文档似乎不适用于我从 Open Frameworks 获得的 Gradle 文件。

关于我试图解决这个问题的说明:

(据我所知,Gradle 插件版本不同于映射的 Gradle 分发版本 in this table。)

关于 Gradle distribution 与 Gradle Experimental plugin 0.11.0 一起使用的版本,我在任何地方找到的唯一来源是 this answer to a related question.我问回答者他们使用的 Android Studio 是什么版本,他们说是 3.1,但没有提到协同签名(我现在已经问过他们了)。

貌似"Android Gradle Plugin"版本一直和AndroidStudio版本一样,所以好像没办法运行Android Gradle 插件版本 3.0 与 Android Studio 3.5.1,正确吗?

所以基于以上,我尝试了:

Android Studio(因此 Gradle 插件版本)2.3.2 实验 Gradle 0.9.3 使用 Gradle 发行版 3.3.0(代码设计 32 位APK - 不知道如何做 64 位)

Android Studio(因此 Gradle 插件版本)3.0.0 实验 Gradle 0.9.3 使用 Gradle 分发 3.3.0(代码设计 32 位APK - 不知道如何做 64 位)

Android Studio(因此 Gradle 插件版本)3.0.0 实验 Gradle 0.11.0 使用 Gradle 发行版 4.1.0 - 我得到一个 Gradle 错误:

*Gradle sync failed: Exception thrown while executing model rule: BaseComponentModelPlugin.Rules#createVariantData(ModelMap<AndroidBinaryInternal>, ModelMap<AndroidComponentSpec>, TaskManager) > afterEach()
    Consult IDE log for more details (Help | Show Log) (21s 58ms)*

我找到了关于如何使用 Gradle HERE 创建 64 位签名 APK 的假定文档,但是列出 ABI 过滤器的建议格式:

ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'

导致错误,Open Frameworks 的项目 build.gradle 尝试包含所有 ABI,如 build.gradle 底部附近的 android.productFlavors 部分所示,如下所示:

def ofRoot(){ return '../../../' }

// Load common functions
apply from: ofRoot()+"libs/openFrameworksCompiled/project/android/common-functions.gradle"

buildscript {
    apply from: "../../../libs/openFrameworksCompiled/project/android/ndk-verify.gradle"

    repositories {
        jcenter()
    }
    dependencies {
        // Using the gradle-experimental version that supports c++
        classpath 'com.android.tools.build:gradle-experimental:0.9.3'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

apply plugin: 'com.android.model.application'

model {
    android {
        // openFrameworks currently only supports compiling against SDK 19
        compileSdkVersion = 23
        buildToolsVersion = "25.0.3"

        defaultConfig.with {
            minSdkVersion.apiLevel    = 23
            targetSdkVersion.apiLevel = 28
            versionCode     =  4
            versionName     = "0.1.1"
        }
    }

    android.ndk {
        moduleName = ofAppModuleName()
        toolchain  = buildToolchain()
        stl        = compilerStl()
        platformVersion = "21"
    }

    android.sources {
        main {
            jni {
                source {
                    srcDirs= appSrcDirs(ofRoot())

                    includes = srcIncludes(ofRoot())
                    excludes = srcExcludes(ofRoot())
                }

                // Link to openFrameworks
                dependencies {
                    project ":openFrameworksProject"  linkage "static"
                }
            }

            manifest {
                source {
                    srcDirs = [ "." ]
                }
            }
            res {
                source {
                    srcDirs = [ "res" ]
                }
            }
            java {
                source {
                    srcDirs = [ "srcJava" ]
                }
            }
            aidl {
                source{
                    srcDirs = ['srcJava']
                }
            }
            renderscript{
                source{
                    srcDirs = ['srcJava']
                }
            }
            jniLibs {
                source {
                    srcDirs = ['libs']
                }
            }
            assets {
                source {
                    srcDirs = ['bin/data'] + addonData(ofRoot())
                }
            }
        }
    }

    android.lintOptions {
        abortOnError  = false
    }

    android.buildTypes {
        release {
            minifyEnabled = false
        }
    }

    // Setup the different types of flavors (arm / x86),
    // and add linker flags based on that
    android.productFlavors {
        getAbis().each { abi ->
            create(getFlavorName(abi)) {
                ndk {
                    abiFilters.add(abi)

                    cppFlags.addAll(coreCppFlags(abi, ofRoot()))
                    cppFlags.addAll(addonCppFlags(abi, ofRoot()))

                    ldLibs.addAll(coreLdLibs(abi, ofRoot()))
                    ldLibs.addAll(addonLdLibs(abi, ofRoot()))

                    ldFlags.addAll(coreLdFlags(abi, ofRoot()))
                    ldFlags.addAll(addonLdFlags(abi, ofRoot()))
                }
            }
        }
    }
}


dependencies {
    addonJavaDependencies(ofRoot()).each { dep ->
        compile(project(path: dep[1] ))
    }
    compile project(path: ':ofAndroidLib')
}

但这会导致在 codesign APK 向导中只有 32 位 Arm 和 386 ABI 选项。

谁能告诉我如何使用 Android Studio(任何版本)为实验插件构建一个代码签名的 64 位 APK?

有一些工具可以使用命令提示符和 zipalign 对 apk 进行签名。这是文档

https://developer.android.com/studio/build/building-cmdline#sign_manually

我相信 zipaline 在实验中仍然有效。 或者您可以使用可以像这样签署 64 位应用程序的第 3 方应用程序

https://github.com/patrickfav/uber-apk-signer

此插件使用 64 位架构签署应用程序。

在 Open Frameworks 论坛的帮助下,经过多日的苦思冥想后,我终于让它开始工作。它不仅涉及代码签名,还涉及使用支持 64 位构建的 OpenFrameworks 版本,以及大量特定设置和步骤。

我对最终有效的步骤、版本和设置的注释在这里:https://forum.openframeworks.cc/t/notes-on-steps-i-took-to-successfully-get-a-64-bit-apk-published-to-the-google-app-store/33722

同时,如果有人对该主题有任何其他有用的信息,请在此处的答案中分享。除了我以外,我会给最多 useful/relevant 答案赏金。