我想有我的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文件。

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


当前回答

如果你像我一样通过命令行构建apk,那么你可以提供签名配置作为参数。

将此添加到build.gradle中

def getStore = { ->
    def result = project.hasProperty('storeFile') ? storeFile : "null"
    return result
}

def getStorePassword = { ->
    def result = project.hasProperty('storePassword') ? storePassword : ""
    return result
}

def getKeyAlias = { ->
    def result = project.hasProperty('keyAlias') ? keyAlias : ""
    return result
}

def getKeyPassword = { ->
    def result = project.hasProperty('keyPassword') ? keyPassword : ""
    return result
}

让你的signingconfig像这样

signingConfigs {
    release {
        storeFile file(getStore())
        storePassword getStorePassword()
        keyAlias getKeyAlias()
        keyPassword getKeyPassword()
    }
}

然后像这样执行gradlew

./gradlew assembleRelease -PstoreFile="keystore.jks" -PstorePassword="password" -PkeyAlias="alias" -PkeyPassword="password"

其他回答

@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/gradle.properties中

RELEASE_STORE_FILE={path to your keystore}
RELEASE_STORE_PASSWORD=*****
RELEASE_KEY_ALIAS=*****
RELEASE_KEY_PASSWORD=*****

修改你的应用/构建。Gradle,并将其添加到android{代码块:

...    
signingConfigs {

   release {
       storeFile file(RELEASE_STORE_FILE)
       storePassword RELEASE_STORE_PASSWORD
       keyAlias RELEASE_KEY_ALIAS
       keyPassword RELEASE_KEY_PASSWORD

       // Optional, specify signing versions used
       v1SigningEnabled true
       v2SigningEnabled true
   }
}

buildTypes {
        release {
            signingConfig signingConfigs.release
        }
}
....

然后你可以运行gradle assemblerrelease


另请参阅signingConfigs Gradle DSL的参考

我有几个问题,我把下面的行放在错误的地方:

signingConfigs {
    release {
        // We can leave these in environment variables
        storeFile file("d:\\Fejlesztés\\******.keystore")
        keyAlias "mykey"

        // These two lines make gradle believe that the signingConfigs
        // section is complete. Without them, tasks like installRelease
        // will not be available!
        storePassword "*****"
        keyPassword "******"
    }
}

确保你把signingConfigs部分放在了android部分:

android
{
    ....
    signingConfigs {
        release {
          ...
        }
    }
}

而不是

android
{
    ....
}

signingConfigs {
   release {
        ...
   }
}

很容易犯这个错误。

Android工作室 转到文件->项目结构或按Ctrl+Alt+Shift+S

查看图片

单击Ok

然后在构建中生成signingconfig。gradle文件。

您可以从命令行请求密码:

...

signingConfigs {
  if (gradle.startParameter.taskNames.any {it.contains('Release') }) {
    release {
      storeFile file("your.keystore")
      storePassword new String(System.console().readPassword("\n\$ Enter keystore password: "))
      keyAlias "key-alias"
      keyPassword new String(System.console().readPassword("\n\$ Enter keys password: "))
    } 
  } else {
    //Here be dragons: unreachable else-branch forces Gradle to create
    //install...Release tasks.
    release {
      keyAlias 'dummy'
      keyPassword 'dummy'
      storeFile file('dummy')
      storePassword 'dummy'
    } 
  }
}

...

buildTypes {
  release {

    ...

    signingConfig signingConfigs.release
  }

  ...
}

...

if-then-else块防止在构建版本时请求密码。虽然else分支是不可达的,它欺骗Gradle创建一个安装…发布的任务。

基本信息。正如https://stackoverflow.com/a/19130098/3664487所指出的,“Gradle脚本可以使用System.console()提示用户输入。readLine方法。”不幸的是,Gradle总是会要求密码,即使你在构建一个调试版本(参见如何使用Gradle创建一个发布签名apk文件?)幸运的是,这是可以克服的,如上所述。