摘要:我们需要为 APK进行数字签名,这样才能发布到 Google Play商店。解决方法很简单,使用 Java的keytool命令创建证书并在 Gradle构建文件的 signingConfigs块中使用就可以办到。下面让我们看看详细讨论。本文选自《巧用Gradle构建Android应用》。

  所有 Android包(APK)文件在部署之前都需要被数字签名,Android使用一个已有的密钥签发调试用的 APK。你可以使用 Java提供的 keytool命令来查看。
默认情况下,调试用的密钥存储库在你的用户目录下的 .Android子目录下面。默认的名字叫作 debug.keystore,并且其密码是 Android。下面示例显示了怎么列举默认的证书。

  示例. 列举调试密钥库(Mac OS x)

>cd~/.android>keytool-list-keystoredebug.keystoreEnterkeystorepassword:("android")Keystoretype:JKSKeystoreprovider:SUNYourkeystorecontains1entryandroiddebugkey,Feb9,2013,PrivateKeyEntry,Certificatefingerprint(SHA1):B7:39:B5:80:BE:A0:0D:6C:84:4F:A1:1F:4B:A1:00:14:12:25:DA:14

  密钥库的类型是 JKS,其代表(很自然的)Java KeyStore,用于公钥和私钥。Java提供另一种类型叫作 JCEKS(Java Cryptography Extensions KeyStore),其可以被用于共享密钥,但是没有被 Android应用程序使用。
  这个密钥库中有一个自签名的证书,别名为 Androiddebugkey,当 APK被部署到连接的设备或者模拟器上时,其被用于签名调试用的 APK。
  为了重设调试用的密钥库,简单地删除 debug.keystore文件,下次部署 app时会重新创建。
你不能部署一个发布版本的 app除非你对其签名了,意味着生成一个发布用的密钥。这也需要使用 keytool工具。一次很简单的运行如下所示。

  示例. 生成发布密钥

keytool-genkey-v-keystoremyapp.keystore-aliasmy_alias-keyalgRSA-keysize2048-validity10000(allononeline)Enterkeystorepassword:(probablyshouldn'tuseuse"password")Re-enternewpassword:(butifyoudid,typeitagain)Whatisyourfirstandlastname?[Unknown]:KenKousenWhatisthenameofyourorganizationalunit?[Unknown]:Whatisthenameofyourorganization?[Unknown]:KousenIT,Inc.WhatisthenameofyourCityorLocality?WhatisthenameofyourStateorProvince?Whatisthetwo-lettercountrycodeforthisunit?IsCN=KenKousen,OU=Unknown,O="KousenIT,Inc.",L=Marlborough,ST=CT,C=UScorrect?Generating2,048bitRSAkeypairandself-signedcertificate(SHA256withRSA)withavalidityof10,000daysfor:CN=KenKousen,OU=Unknown,O="KousenIT,Inc.",L=Marlborough,ST=CT,C=USEnterkeypasswordfor<my_alias>(RETURNifsameaskeystorepassword):[Storingmyapp.keystore]Whatisthetwo-lettercountrycodeforthisunit?IsCN=KenKousen,OU=Unknown,O="KousenIT,Inc.",L=Marlborough,ST=CT,C=UScorrect?Generating2,048bitRSAkeypairandself-signedcertificate(SHA256withRSA)withavalidityof10,000daysfor:CN=KenKousen,OU=Unknown,O="KousenIT,Inc.",L=Marlborough,ST=CT,C=USEnterkeypasswordfor<my_alias>(RETURNifsameaskeystorepassword):[Storingmyapp.keystore]

  RSA算法被用于生成公私钥对,大小为 2KB,使用 SHA256进行签名,10 000(27年多)天有效期。
  你现在可以使用 jarsigner和 zipalign工具来为你的 APK签名了,但是让 Gradle来做会更容易。
  添加 signingConfigs块作为 Android闭包的一个子块,如下所示。

  示例. 在模块构建文件中的signingCons块

android{//...othersections...signingConfigs{release{keyAlias'my_alias'keyPassword'password'storeFilefile('/Users/kousen/keystores/myapp.keystore')storePassword'password'}}}

  你可能不想将密码硬编码在构建文件中。幸运的是,你可以把它们放到 gradle.properties文件中,或者从命令行指定。
  从 DSL文档中,signingConfigs块委托给一个 SigningConfig的类,其包含四个常用的属性:

keyAlias:当签发一个特定的密钥时在 keytool中被使用。

keyPassword:在签发过程中使用的一个特定密钥的密码。

storeFile:包含密钥和证书的磁盘文件,由 keytool生成。

storePassword:密钥库文件自身使用的密码。 还有一个 storeType属性(默认为 JKS, 如示例 2-29所示),但是这个属性很少使用。 为了使用新的配置,添加一个 signingConfig属性到 release构建类型。

示例. 在发布构建中使用签名配置

android{//其他段buildTypes{release{//其他设置signingConfigsigningConfigs.release}}}

  当你在 Gradle中调用 assembleRelease任务的时候,构建为在 app/build/outpu/apk目录下生成一个发布版本的 APK。

  示例. 运行assembleRelease任务

>./gradlewassembleRelease:app:preBuildUP-TO-DATE:app:preReleaseBuildUP-TO-DATE//...太多任务:app:zipalignReleaseUP-TO-DATE:app:assembleReleaseUP-TO-DATEBUILDSUCCESSFULkousenatkrakatoain~/Documents/AndroIDstudio/MyAndroidApp>ls-lapp/build/outputs/apktotal12088-rw-r--r--1kousenstaff1275604Aug2415:05app-debug.apk-rw-r--r--1kousenstaff1275481Aug2621:04app-release.apk

  注意——这很重要— —不要丢失密钥库。如果丢了,你将不能发布任何关于你的 app的更新,因为所有的版本都必须要用同样的密钥签名。
  本文选自《巧用Gradle构建Android应用》,点此链接可在博文视点官网查看。
                      
  想及时获得更多精彩文章,可在微信中搜索“博文视点”或者扫描下方二维码并关注。