Android 为什么发布版本变量总是可调试的?

Android 为什么发布版本变量总是可调试的?,android,android-studio,android-signing,Android,Android Studio,Android Signing,我是否通过以下方式创建“发布”APK: 在Android Studio中使用生成签名APK 选择发布版本变量并使用工具->构建APK 运行assembleRelease任务 。。。生成的APK始终具有debuggable=true,我已通过尝试将其上传到Google Play确认了这一点,Google Play说: “上载失败。您上载了可调试的APK。出于安全原因,您需要先禁用调试,然后才能在Google Play中发布。” (仅)清单未指定可调试属性。Gradle为release指定deb

我是否通过以下方式创建“发布”APK:

  • 在Android Studio中使用生成签名APK
  • 选择发布版本变量并使用工具->构建APK
  • 运行assembleRelease任务
。。。生成的APK始终具有debuggable=true,我已通过尝试将其上传到Google Play确认了这一点,Google Play说:

“上载失败。您上载了可调试的APK。出于安全原因,您需要先禁用调试,然后才能在Google Play中发布。”

(仅)清单未指定可调试属性。Gradle为release指定debuggable=false,为debug指定true,见下文

我错过了什么?可调试状态从何而来,为什么版本生成类型声明中的debuggable=false被忽略?我不想将debuggable=false添加到清单中,并且必须手动启用/禁用它

app/build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion '26.0.0'
    defaultConfig {
        applicationId "com.myapp.android"
        minSdkVersion 14
        targetSdkVersion 26
        versionCode 5
        versionName 5
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    signingConfigs {
        release {
            storeFile rootProject.file("keystore.jks")
            if (storeFile.exists()) {
                def config = new Properties()
                config.load(new FileInputStream(rootProject.file("keystore.passwords")))
                storePassword config.KeystorePassword
                keyAlias config.KeyAlias
                keyPassword config.KeyPassword
            }
        }
    }

    buildTypes {
        release {
            debuggable false
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
        }
        debug {
            debuggable true
            applicationIdSuffix ".debug"
        }
    }

    dataBinding {
        enabled = true
    }

    lintOptions {
        disable 'RtlHardcoded'
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    // Copy release APK to project root
    task copyReleaseApk(type: Copy) {
        from 'build/outputs/apk'
        into '..'
        include '**/*release.apk'
    }

    afterEvaluate {
        if (tasks.findByPath("packageRelease") == null) {tasks.create("packageRelease")}
        tasks.findByPath("packageRelease").finalizedBy(copyReleaseApk)
    }

}

ext {
    // Single place to specify the support library version
    supportLibraryVersion = '26.0.0-beta2'
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
        exclude group: 'com.google.code.findbugs'
        exclude module: 'espresso-idling-resource'
        exclude group: "javax.inject"
    })
    implementation 'com.android.support.test.espresso:espresso-contrib:2.2.2'

    // Dagger dependency injection
    implementation 'com.google.dagger:dagger:2.10'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.10'
    implementation 'com.google.dagger:dagger-android:2.10'
    implementation 'com.google.dagger:dagger-android-support:2.10'
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.10'

    implementation "com.android.support:appcompat-v7:$supportLibraryVersion"
    implementation "com.android.support:design:$supportLibraryVersion"
    implementation "com.android.support.constraint:constraint-layout:1.0.2"

    implementation "com.jakewharton.timber:timber:4.5.1"
    implementation "com.squareup.phrase:phrase:1.1.0"
    implementation "com.squareup.retrofit2:retrofit:2.2.0"
    implementation "com.squareup.retrofit2:converter-gson:2.2.0"
    implementation "com.squareup.okhttp3:logging-interceptor:3.7.0"
    implementation 'net.danlew:android.joda:2.9.9'

    testImplementation 'junit:junit:4.12'
    implementation 'com.google.firebase:firebase-crash:11.0.0'
    androidTestImplementation 'junit:junit:4.12'
}

apply plugin: 'com.google.gms.google-services'
更新1:我尝试将debuggable=false添加到清单中,但没有任何区别,生成的APK仍然无法上传到Google Play

更新2:我使用APK分析器将APK加载回Android Studio,这样可以很容易地查看清单,它们都包括。。。。可调试=真。它是从哪里来的

更新3:assembleRelease在我的本地计算机和CI服务器(BuddyBuild)上生成一个可调试的APK

更新4:一次干净的重建(包括删除构建文件夹)和在清除缓存的情况下重新启动Android Studio没有任何区别


更新5:假设debuggable=true状态可能来自其中一个依赖项似乎是合理的,但如果是这种情况,可以覆盖哪一个,以及如何覆盖?

这是因为您可能有增量生成,默认情况下,所有增量生成都假定为可调试的

根据《公约》,它指出:

支持真正的调试构建。开发人员不再需要添加 android:manifest中标记的可调试属性 -构建工具会自动添加属性。在Eclipse/ADT中,所有 增量构建被假定为调试构建,因此工具插入
android:debuggable=“true”。导出已签名的版本生成时 工具不会添加该属性。在Ant中,Ant调试命令 自动插入android:debuggable=“true”属性,同时 ant的释放不起作用。如果手动设置了android:debuggable=“true”, 然后ant发行版将实际执行调试构建,而不是发行版 建造


由于该项目以API 26为目标,并使用android gradle插件的3.0.0-alpha4、26.0.0-beta2构建工具和gradle 4.0-rc1,我认为我应该检查该问题是否与这些预发布工具的问题相关。所以我回到了API 25和gradle 3.3的稳定版本,gradle插件2.3.3和构建工具25.0.3。这有点乏味,因为我不得不将所有Java8语法从源代码降级到Java7。但是完成了这项工作后,构建过程现在可以按预期工作,并生成不包含debuggable=“true”标志的发布APK工件,并且可以上传到GooglePlay。你确定你上传的是正确的APK吗?是的,我试过用上述各种方法从多个文件夹位置生成的许多APK,并在生成新的APK之前清除文件夹。如果你删除
copyreaseAPK
用法,会发生这种情况吗?@petey我尝试过禁用它,但它没有效果——APK仍然包含调试数据。“假设debuggable=true状态可能来自其中一个依赖项似乎是合理的,但如果是这种情况,那么应该覆盖哪个以及如何覆盖?”——在Android Studio中,打开清单,然后选择“合并清单”子选项卡。此外,如果您使用
aapt
,?“导出已签名的发布版本时,工具不会添加属性”-如果这意味着使用生成已签名的APK或生成APK,则这不是问题所在,因为这两种方法仍会生成可调试的APK。我尝试了干净的完全重建,但没有成功。清单似乎仍然需要包含一个显式的debugable=“false”