我想有我的Gradle构建创建一个发布签名apk文件使用Gradle。

我不确定代码是否正确,或者我在做gradle构建时是否缺少一个参数?

这是build.gradle/build.gradle中的一些代码。节文件:

android {
    ...
    signingConfigs {
        release {
            storeFile(file("release.keystore"))
            storePassword("******")
            keyAlias("******")
            keyPassword("******")
        }
    }
}

Gradle构建成功完成,在我的build/apk文件夹中,我只看到…-release-unsigned.apk和…-debug-unaligned.apk文件。

对如何解决这个问题有什么建议吗?


当前回答

我在计算这个过程中获得了很多乐趣。下面是我的演练。

如何在IntelliJ中创建gradle构建文件(v.13.1.4) 本演练假设您知道如何生成密钥存储库文件。 为了本教程的工作,你需要你的keystore文件位于你的应用文件夹,你需要有你的zipalign.exe文件位于'SDK-ROOT\tools'。这个文件通常在“SDK-ROOT\build-tools”文件夹中,在这个文件夹下,它将在最高的api文件夹中(alpha或beta我推荐alpha版本)。

对于那些希望直接跳到这里的人来说,这里是gradle构建文件。

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.9.+'
    }
}
apply plugin: 'android'

repositories {
    mavenCentral()
}
android {
    compileSdkVersion 19
    buildToolsVersion '20.0.0'
    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    signingConfigs {
        playstore {
            keyAlias 'developers4u'
            keyPassword 'thisIsNotMyRealPassword'
            storeFile file('developers4u.keystore')
            storePassword 'realyItIsNot'
        }
    }
    buildTypes {
        assembleRelease {
            debuggable false
            jniDebugBuild false
            runProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            zipAlign true
            signingConfig signingConfigs.playstore
        }
    }
}

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

You can build part of this build file (above) from menu option: File/Project Structure From here select Facets and click 'Android-Gradle(App). From here you will see tabs: 'Properties', 'Signing', 'Flavors', 'Build Types' and 'Dependencies' for this walk-through we will just be using 'Signing' and 'Build Types'. Under 'Build Types' (in the name section) enter any name that you wish to identify your build type configuration and in the other 4 fields enter your keystore information (setting the keystore path the the one under your app folder).

在“构建类型”下,在名称字段中输入值“assemblerrelease”,“Debuggable”应该设置为false,“Jni Debug Build”应该设置为false,“Run Proguard”设置为true,“Zip Align”设置为true。这将生成构建文件,但不是像上面描述的那样,您必须随后向构建文件添加一些东西。这里的ProGuard文件位置将在gradle构建文件中手动设置。(如上所述)

你需要添加的DSL容器如下所示:

android {
    ....
    compileSdkVersion 19
    buildToolsVersion '20.0.0'
    defaultConfig {
        minSdkVersion 8
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    ....
}

您还必须添加:

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

注意上面的DSL容器('dependencies')应该在配置文件的底部,而不是在android DSL容器内。 为了从IntelliJ菜单中构建依赖项容器,选择:File/Project Structure。再次选择Facets,然后选择Android-Gradle(app)。您将看到与上述相同的5个选项卡。选择“Dependencies”选项卡并添加所需的依赖项。

所有这些都完成后,您应该会看到一个Gradle构建文件,类似于本演练开头的文件。 要构建你签名的zip对齐版本,你需要打开Gradle任务。你可以通过选择视图/工具窗口/Gradle来进入这个窗口。 在这里你可以双击' assembleassemblerrelease '。这将生成可部署的APK。

编译你的版本时可能出现的潜在问题有(但不限于):你的Gradle构建文件在错误的位置。有两个Gradle构建文件;一个在应用程序根文件夹中,另一个在应用程序根下的应用程序文件夹中。你必须使用后者。

你也可能有棉绒问题。(注意:Android Developer Studio在发现Lint问题方面比IntelliJ要好得多,当你试图从菜单选项中生成签名APK时,你会注意到这一点)

为了解决lint问题,你需要把下面的DSL容器放入android容器中(在顶部):

android {
        ....
    lintOptions {
        abortOnError false
    }
    ....
}

putting this inside your android DSL container will cause an error file to be generated in the build folder (directly under your app folder) the file name should be something like 'lint-results-release-fatal.html' this file will tell you the the class where the error occurred. Another file that will be generated is an XML file that contains the 'issue ID' associated with the lint error. The file name should be something like 'lint-results-release-fatal.xml'. Somewhere near the top of the file you will see a node 'issue' inside which you will see something similar to 'id="IDOfYourLintProblem"'

要纠正此问题,打开项目中'lint-results- assemblerrelease -fatal.html'文件中列出的文件,并在Java类文件中类名上方输入以下代码行:@SuppressLint("IDOfYourLintProblem")。你可能需要导入'android.annotation.SuppressLint;'

所以你的java类文件应该是这样的:

package com.WarwickWestonWright.developers4u.app.CandidateArea;

import android.annotation.SuppressLint;
... other imports

@SuppressLint("IDOfYourLintProblem")
public class SearchForJobsFragment extends Fragment {... rest of your class definition}

请注意,抑制lint错误并不总是最好的想法,你可能会更好地改变导致lint错误的代码。

另一个可能发生的问题是,如果您没有为Gradle HOME环境变量设置环境变量。这个变量名为'GRADLE_HOME',应该设置为gradle主目录的路径,类似于'C:\gradle-1.12' 有时候你可能还想设置ANDROID_HOME的环境变量将其设置为YOUR-SDK-Root\sdk

完成后,返回Gradle任务窗口,双击assembleassemblerrelease。

如果一切都成功了,你应该能够进入app\build\apk文件夹并找到你的可部署apk文件。

其他回答

这是Kotlin构建脚本(build.gradle.kts)的另一个答案,与Willi Mentzel的答案不同。

它尝试从本地读取。属性文件,返回到OS环境变量。它在像GitHub Actions这样的ci中特别有用(你可以在存储库设置中创建环境秘密)。

注意,我使用的是Kotlin 1.6.10和Gradle 7.4.2和Android Gradle Plugin (AGP) 7.0.4。

import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties
// ...

val environment = System.getenv()
fun getLocalProperty(key: String) = gradleLocalProperties(rootDir).getProperty(key)
fun String.toFile() = File(this)

android {
    signingConfigs {
        create("MySigningConfig") {
            keyAlias = getLocalProperty("signing.keyAlias") ?: environment["SIGNING_KEY_ALIAS"] ?: error("Error!")
            storeFile = (getLocalProperty("signing.storeFile") ?: environment["SIGNING_STORE_FILE"] ?: error("Error!")).toFile()
            keyPassword = getLocalProperty("signing.keyPassword") ?: environment["SIGNING_KEY_PASSWORD"] ?: error("Error!")
            storePassword = getLocalProperty("signing.storePassword") ?: environment["SIGNING_STORE_PASSWORD"] ?: error("Error!")
            enableV1Signing = true
            enableV2Signing = true
        }
    }

    buildTypes {
        release {
            signingConfig = signingConfigs["MySigningConfig"]
            isMinifyEnabled = true
            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
        }
    }
}

如前所述,你可以有一个本地。属性文件在你的项目的根属性值:

signing.keyAlias=My key
signing.keyPassword=zyxwvuts
signing.storePassword=abcdefgh
signing.storeFile=C\:\\Users\\Mahozad\\keystore.jks

... 或者你可以在你的操作系统上设置/创建环境变量;例如,创建一个名为SIGNING_KEY_ALIAS的环境变量:

Windows命令提示符:setx SIGNING_KEY_ALIAS“我的密钥” Linux终端:export SIGNING_KEY_ALIAS="My key"

注意:正如其他答案所提到的,不要添加您的本地。属性文件到你的版本控制系统(如Git),因为它将你的秘密信息,如密码等暴露给公众(如果它是一个公共存储库)。

用上面提到的3种方法中的任意一种生成APK。

就我而言,我上传了错误的apk到另一个应用程序的发布中。

@Destil的答案很好,如果你可以在所有项目中重用相同的配置。或者,Android Studio自带本地文件。可以使用的属性文件,但它应该是ide生成的,我找不到一种方法来扩展它从Android Studio。

这是@jonbo回答的一个变体。这个答案允许项目特定的设置,但它带来了一些开发人员的开销。具体来说,需要大量的样板文件来将signingConfigs定义移动到一个单独的文件中——特别是当您需要为多个项目这样做时,这是选择这个解决方案而不是Destil的主要原因。这可以通过包含线条在一定程度上得到缓解

apply plugin: 'com.android.application'

在凭证文件中,因为这将允许IDE完成。

最后,这里的大多数解决方案不允许在不提供语法上(如果不是语义上)有效的signingConfigs定义的情况下以调试模式构建项目(自动处理调试签名)。如果您不需要从给定的机器生成一个发布版本,那么这个额外的步骤可以被视为一个不必要的障碍。另一方面,它可以帮助在生产中运行调试构建的无知或懒惰的同事。

这个解决方案将允许调试构建而完全不用担心凭证,但是它将需要有效的凭证来生成发布构建,并且它只需要很少的样板文件。然而,作为一个缺点,它可能会鼓励其他人用真实的凭证替换虚拟值,并且没有办法防止这种情况。

// app/build.gradle
// Define this structure in signing.gradle to enable release builds.
ext.signing = [
        storeFilePath : 'path/to/keystore',
        storePassword : 'keystore password',
        keyAlias      : 'key alias',
        keyPassword   : 'key password',
]

if (file('signing.gradle').exists()) {
    apply from: 'signing.gradle'
}

android {
    ...
    signingConfigs {
        release {
            storeFile file(project.signing.storeFilePath)
            storePassword project.signing.storePassword
            keyAlias project.signing.keyAlias
            keyPassword project.signing.keyPassword
        }
    }
    buildTypes {
        debug { ... }
        release {
            signingConfig signingConfigs.release
            ...
        }
    }
}

这将创建一个虚拟属性,纯粹用于生成语法上有效的构建文件。在调试构建阶段,分配给ext.signing属性的值是不相关的。要启用发布版本,请将ext.signing复制到signing中。Gradle并将虚拟值替换为有效凭证。

// signing.gradle
ext.signing = [
        storeFilePath : 'real/keystore',
        storePassword : 'real keystore password',
        keyAlias : 'real key alias',
        keyPassword : 'real key password',
]

当然,签名。gradle应该被VCS忽略。

我设法解决它添加这段代码,并与gradle构建:

android {
    ...
    signingConfigs {
        release {
            storeFile file("release.keystore")
            storePassword "******"
            keyAlias "******"
            keyPassword "******"
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

这将生成一个已签名的发布apk文件。

在更新的Android Studio中,有一种非常简单的GUI方式,它也可以填充Gradle文件。

File ->项目结构 选择主模块('app'或其他自定义名称) 签名选项卡-> +图像添加新的配置 在右侧填写数据 然后自动创建Gradle文件 您必须手动添加一行signingConfig signingConfig。builtTypes{release{}}中的yourconfig名称

图片:

两个重要的(!)注意事项:

(12/15)编辑

要创建签名APK,你必须打开Android Studio的Terminal选项卡(主界面的底部)并发出命令。/gradlew assemblerrelease 如果你忘记了keyAlias(经常发生在我身上),你将不得不启动Build -> Generate Signed APK来启动这个过程,并看到别名密钥的名称。