1.
配置要发布的应用
在收集所有支持材料后,您可以开始配置要发布的应用。本部分总结了我们建议您在发布应用之前对源代码、资源文件和应用清单进行的配置更改。尽管本部分列出的大部分配置更改为可选更改,但却是一些不错的编码实践,我们建议您实施这些更改。在某些情况下,您可能已在开发流程中进行了这些配置更改。
选择一个适当的软件包名称
确保您选择的软件包名称适用于应用的整个生命周期。在向用户分发应用后,您将无法更改软件包名称。您可以在应用的清单文件中设置此软件包名称。如需了解详细信息,请参阅 package 属性文档。
关闭日志记录和调试
在构建要发布的应用之前,务必关闭日志记录并停用调试选项。您可以通过在源文件中移除对 Log
方法的调用来关闭日志记录。您可以通过在清单文件中将 android:debuggable
属性从 <application>
标记中移除,或通过在清单文件中将 android:debuggable
属性设为 false
来停用调试。另外,移除在您的项目中创建的所有日志文件或静态测试文件。
您还应移除您添加到代码中的所有 Debug
跟踪调用,例如 startMethodTracing()
和 stopMethodTracing()
方法调用。
2.
清理项目目录
清理项目,并确保其符合 Android 项目中描述的目录结构。将散乱文件或孤立文件留在项目中会妨碍您编译应用,而且可能会导致应用行为不可预测。您至少应执行以下清理任务:
- 查看
jni/
、lib/
和src/
目录的内容。jni/
目录应仅包含与 Android NDK 关联的源文件,例如.c
、.cpp
、.h
和.mk
文件。lib/
目录应仅包含第三方库文件或专有库文件,包括预构建共享库和静态库(例如,.so
文件)。src/
目录应仅包含您的应用的源文件(.java
和.aidl
文件)。src/
目录不应包含任何.jar
文件。 - 检查项目,查看是否有应用不使用的私有或专有数据文件,并移除它们。例如,查看项目的
res/
目录是否有您不再使用的旧的可绘制对象文件、布局文件和值文件,并删除它们。 - 检查
lib/
目录,查看是否有应用不再使用的测试库,并移除它们。 - 查看
assets/
目录的内容以及res/raw/
目录是否有需要在发布前更新或移除的原始资源文件和静态文件。
查看并更新您的清单和 Gradle 构建设置
验证是否已正确设置以下清单和构建文件项目:
- <uses-permission> 元素
您应仅指定那些与应用相关且必需的权限。
android:icon
和android:label
属性这些属性位于 <application> 元素中,您必须为它们指定相应的值。
android:versionCode
和android:versionName
属性。这些属性位于 <manifest> 元素中,我们建议您为它们指定相应的值。如需了解详细信息,请参阅对您的应用进行版本控制。
3.
对您的应用进行版本控制
版本控制是应用升级和维护策略的关键组成部分。版本控制很重要,因为:
- 用户需要了解其设备上所安装应用的具体版本信息,以及可供安装的升级版本。
- 其他应用(包括您作为套件发布的其他应用)需要查询系统获取应用的版本,以确定兼容性和识别依赖关系。
- 发布应用时所使用的服务可能也需要查询应用的版本,以便它们可以向用户显示版本。发布服务可能还需要检查应用版本,以确定兼容性和建立升级/降级关系。
Android 系统不会使用应用版本信息对第三方应用的升级、降级或兼容性进行限制,而是由您负责在您的应用内执行版本限制,或通知用户版本限制与局限性。不过,Android 系统会根据构建文件中 minSdkVersion
设置的说明强制执行系统版本兼容性。该设置允许应用指定与其兼容的最低系统 API。如需了解详细信息,请参阅指定最低系统 API 版本。
设置应用版本信息
要为您的应用定义版本信息,请在 Gradle 构建文件中为版本设置设定相应的值。这些值随后将在构建流程中合并到您应用的清单文件中。
注:如果您的应用直接在 <manifest>
元素中定义应用版本,Gradle 构建文件中的版本值将替换清单中的设置。此外,在 Gradle 构建文件中定义这些设置还让您可以为应用的不同版本指定不同的值。为了在合并清单时提高灵活性和避免潜在覆盖,您应当从 <manifest>
元素中移除这些属性,并改在 Gradle 构建文件中定义您的版本设置。
可配置两个设置,您应始终为它们定义相应的值:
versionCode
- 一个整数,用作内部版本号。此数字仅用于确定一个版本是否比另一个版本更新,数字越大表示版本越新。这不是显示给用户的版本号;后者通过下面的versionName
设置设定。该值是一个整数,其他应用可以通过编程方式对其进行评估,例如,检查升级或降级关系。您可以将该值设为您需要的任何整数,不过,您应确保应用的每个后续版本都使用一个较大的值。系统不强制执行此行为,但通常会针对后续版本增大此值。
通常,发布应用的第一个版本时需要将
versionCode
设为 1,之后为每个发布版本单调增大此值,无论发布的是主版本还是次版本。这表示versionCode
值不一定与用户可见的应用发布版本非常相似(请参阅下面的versionName
)。应用和发布服务不应向用户显示此版本值。警告:Google Play 允许的最大
versionCode
值为 2100000000。versionName
- 一个字符串,用作显示给用户的版本号。可以作为原始字符串或对字符串资源的引用指定此设置。此值是一个字符串,您可以使用 <major>.<minor>.<point> 字符串或任何其他类型的绝对或相对版本标识符来描述应用版本。除了向用户显示之外,
versionName
没有其他用途。
您可以将这些设置包含到 defaultConfig {}
块中(嵌套在模块的 build.gradle
文件的 android {}
块内部),为它们定义默认值。随后,您可以通过为各个构建类型或产品风味定义单独的值,为应用的不同版本替换这些默认值。下面的 build.gradle
文件显示了 defaultConfig {}
块和 productFlavors {}
块中的 versionCode
和 versionName
设置。
android {
...
defaultConfig {
...
versionCode 2
versionName "1.1"
}
productFlavors {
demo {
...
versionName "1.1-demo"
}
full {
...
}
}
}
在本示例的 defaultConfig {}
块中,versionCode
值表示当前 APK 包含应用的第二个版本,versionName
字符串则指定应用将以版本 1.1 向用户显示。此 build.gradle
文件还定义了两个产品风味,即“demo”和“full”。由于“demo”产品风味将 versionName
定义为“1.1-demo”,“demo”将使用此 versionName
,而不是默认值。“full”产品风味块未定义 versionName
,因此它将使用默认值 1.1。
Android 框架提供了一个 API,让您可以查询系统,获取有关应用的版本信息。要获取版本信息,请使用 PackageManager
的 getPackageInfo(java.lang.String, int)
方法。
注:如果使用 Instant Run,Android Studio 会自动将 versionCode
设置为 MAXINT
,将 versionName
设置为 INSTANTRUN
。
指定 API 级别要求
如果您的应用需要特定的最低版本的 Android 平台,您可以在应用的 build.gradle
文件中以 API 级别设置的形式指定版本要求。在构建流程中,这些设置将合并到您应用的清单文件中。指定 API 级别要求可确保只能将您的应用安装在运行兼容的 Android 平台版本的设备上。
注:如果您直接在应用的清单文件中指定 API 级别要求,构建文件中的对应设置将替换清单文件中的设置。此外,在 Gradle 构建文件中定义这些设置还让您可以为应用的不同版本指定不同的值。为了在合并清单时提高灵活性和避免可能发生的覆盖,您应当从 <uses-sdk>
元素中移除这些属性,并改在 Gradle 构建文件中定义您的 API 级别设置。
存在两种 API 级别设置:
minSdkVersion
- 可运行应用的最低版本的 Android 平台,由该平台的 API 级别标识符指定。targetSdkVersion
- 指定运行应用的目标 API 级别。在某些情况下,这允许应用使用在目标 API 级别中定义的清单元素或行为,而不是仅限于使用那些针对最低 API 级别定义的元素或行为。
要在 build.gradle
文件中指定默认的 API 级别要求,请将上面的一个或多个设置添加到 defaultConfig {}
块中,嵌套在 android {}
块内。您还可以通过将设置添加到构建类型或产品风味的方式,为应用的不同版本替换这些默认值。下面的 build.gradle
文件可以指定 defaultConfig {}
块中默认的 minSdkVersion
和 targetSdkVersion
设置,并为一个产品风味替换 minSdkVersion
。
android {
...
defaultConfig {
...
minSdkVersion 14
targetSdkVersion 24
}
productFlavors {
main {
...
}
afterLollipop {
...
minSdkVersion 21
}
}
}
在准备安装您的应用时,系统将检查这些设置的值,并将其与系统版本比较。如果 minSdkVersion
值大于系统版本,系统将阻止应用安装。
如果您不指定这些设置,系统将假设您的应用与所有平台版本兼容。
如需了解详细信息,请参阅 <uses-sdk>
清单元素文档以及 API 级别文档。有关 Gradle 构建设置,请参阅配置构建变体。
4.
签署 APK
无论您选择如何管理您的密钥和密钥库,您都可以使用 Android Studio 签署您的 APK(使用上传密钥或应用签名密钥),以手动方式或通过配置您的构建流程自动签署 APK。
如果您选择自行管理和保护您的应用签名密钥和密钥库,您将使用您的应用签名密钥签署您的 APK。如果您选择使用 Google Play 应用签名管理和保护您的应用签名密钥和密钥库,那么,您将使用您的上传密钥签署您的 APK。
生成密钥和密钥库
您可以使用 Android Studio 生成应用签名或上传密钥,步骤如下:
- 在菜单栏中,点击 Build > Generate Signed APK。
- 从下拉菜单中选择一个模块,然后点击 Next。
-
点击 Create new 以创建一个新密钥和密钥库。
-
在 New Key Store 窗口上,为您的密钥库和密钥提供以下信息,如图 3 所示。
图 3. 在 Android Studio 中创建新的密钥库。
密钥库
- Key store path:选择创建密钥库的位置。
- Password:为您的密钥库创建并确认一个安全的密码。
密钥
- Alias:为您的密钥输入一个标识名。
- Password:为您的密钥创建并确认一个安全的密码。此密码应当与您为密钥库选择的密码不同
- Validity (years):以年为单位设置密钥的有效时长。密钥的有效期应至少为 25 年,以便您可以在应用的整个生命期内使用相同的密钥签署应用更新。
- Certificate:为证书输入一些关于您自己的信息。此信息不会显示在应用中,但会作为 APK 的一部分包含在您的证书中。
填写完表单后,请点击 OK。
- 如果您想生成一个使用您的新密钥签署的 APK,则继续转到手动签署 APK,如果您只想生成一个密钥和密钥库而不签署 APK,则点击 Cancel。
- 如果您想选择使用 Google Play 应用签名,则转到管理您的应用签名密钥,并按照说明设置 Google Play 应用签名。
手动签署 APK
您可以使用 Android Studio 手动生成签署的 APK,既可以一次生成一个 APK,也可以一次为多个构建变体生成 APK。除了手动签署 APK 外,您还可以将 Gradle 构建设置配置为在构建流程期间自动处理签署。本部分将介绍手动签署流程。如需详细了解如何在构建流程中签署应用,请参阅配置构建流程以自动签署您的 APK。
要在 Android Studio 中手动签署用于发布的 APK,请按以下步骤操作:
- 点击 Build > Generate Signed APK 以打开 Generate Signed APK 窗口。(如果您刚刚按上述说明生成了一个密钥和密钥库,则此窗口已处于打开状态。)
-
在 Generate Signed APK Wizard 窗口上,选择一个密钥库和一个私钥,并为它们输入密码。(如果您刚刚在上一部分中创建密钥库,这些字段将自动填充。)然后,点击 Next。
注:如果您使用 Google Play 应用签名,您应在此处指定您的上传密钥。如果改为自行管理您的应用签名密钥和密钥库,您应指定您的应用签名密钥。如需了解详细信息,请参阅上文的管理您的密钥。
图 4. 在 Android Studio 中选择一个私钥。
-
在下一个窗口上,为签署的 APK 选择一个目的地、选择构建类型、选择产品风味(如果适用),然后点击 Finish。
图 5. 为已选择的产品风味生成签署的 APK。
注:如果您的项目使用多个产品风味,那么在 Windows/Linux 上按住 Ctrl 键或者在 Mac OS X 上按住 Command 键可以选择多个产品风味。Android Studio 将为选择的每个产品风味生成单独的 APK。
在流程完成后,您会在上面选择的目标文件夹中找到签署的 APK。现在,您可以通过像 Google Play 商店一样的应用市场或者您选择的机制分发签署的 APK。要详细了解如何将签署的 APK 发布到 Google Play 商店,请参阅开始发布。要详细了解其他分发选项,请阅读替代分发选项。
为了确保用户将更新成功安装到您的应用中,您需要在应用的整个生命周期内使用相同的证书签署 APK。要详细了解使用相同密钥签署所有应用的各种好处,请参阅下面的签署注意事项。如需了解有关保护您的私钥和密钥库的详细信息,请参阅下文的保护您的密钥。
配置构建流程以自动签署您的 APK
在 Android Studio 中,您可以创建一个签署配置并将其分配至您的发布构建类型,将您的项目配置为在构建流程中自动签署发布 APK。一个签署配置包含一个密钥库位置、密钥库密码、密钥别名和密钥密码。要使用 Android Studio 创建一个签署配置并将其分配至您的发布构建类型,请按以下步骤操作:
- 在 Project 窗口中,右键点击您的应用并点击 Open Module Settings。
- 在 Project Structure 窗口左面板中的 Modules 下,点击您想要签署的模块。
- 点击 Signing 标签,然后点击 Add。
。
-
选择您的密钥库文件,为此签署配置输入一个名称(因为您可能创建多个配置),然后输入所需的信息。
图 6. 用于创建新签署配置的窗口。
- 点击 Build Types 标签。
- 点击 release 构建。
-
在 Signing Config 下,选择您刚创建的签署配置。
图 7. 在 Android Studio 中选择一个签署配置。
- 点击 OK。
现在,在您每一次使用 Android Studio 构建发布构建时,IDE 都会使用您指定的签署配置自动签署 APK。您可以在所构建模块项目目录内部的 build/outputs/apk/
文件夹中找到签署的 APK。
在您创建签署配置时,您的签署信息将以纯文本形式包含到 Gradle 构建文件中。如果您是团队协作开发或者公开分享自己的代码,那么您应当从构建文件中移除签署信息并将其单独存储,从而确保此信息的安全。要详细了解如何从构建文件中移除您的签署信息,请参阅从您的构建文件中移除签署信息。要详细了解如何保证签署信息安全,请参阅保护您的密钥。
以不同方式签署每个产品风味
如果您的应用使用多个产品风味并且您想要以不同方式签署每个风味,则可以创建更多签署配置并将其按风味分配:
- 在 Project 窗口中,右键点击您的应用并点击 Open Module Settings。
- 在 Project Structure 窗口左面板中的 Modules 下,点击您想要签署的模块。
- 点击 Signing 标签,然后点击 Add。
。
-
选择您的密钥库文件,为此签署配置输入一个名称(因为您可能创建多个配置),然后输入所需的信息。
图 8. 用于创建新签署配置的窗口。
- 如果需要,请重复第 3 步和第 4 步,直到您完成所有签署配置的创建。
- 点击 Flavors 标签。
- 点击您想要配置的风味,然后从 Signing Config 下拉菜单中选择合适的签署配置。
图 9. 按产品风味配置签署设置。
重复操作以配置任何其他产品风味。
- 点击 OK。
您还可以在 Gradle 配置文件中指定您的签署设置。如需了解详细信息,请参阅配置签署设置。
签署 Android Wear 应用
如果您构建一个 Android Wear 应用,则签署此应用的流程不同于本页面上介绍的流程。请参阅与打包和发布 Android Wear 应用有关的信息。
签署注意事项
在应用的预期生命周期内,您应使用相同证书签署所有 APK。这么做的原因有多个:
- 应用升级:当系统安装应用的更新时,它会比较新版本和现有版本中的证书。如果证书匹配,则系统允许更新。如果您使用不同的证书签署新版本,则必须为应用分配另一个软件包名称 - 在此情况下,用户将新版本作为全新应用安装。
- 应用模块化:Android 允许通过相同证书签署的多个 APK 在同一个进程中运行(如果应用请求这样),以便系统将它们视为单个应用。通过此方式,您可以在模块中部署您的应用,且用户可以独立更新每个模块。
- 通过权限共享代码/数据:Android 提供基于签名的权限执行,以便应用可以将功能展示给使用指定证书签署的另一应用。通过使用同一个证书签署多个 APK 并使用基于签名的权限检查功能,您的应用可采用安全的方式共享代码和数据。
如果您计划支持升级应用,请确保您的应用签名密钥的有效期超出该应用的预期生命周期。建议有效期为 25 年或以上。当密钥有效期过期后,用户将不能再无缝升级到应用的新版本。
如果您计划在 Google Play 上发布您的应用,您用于签署这些 APK 的密钥的有效期必须在 2033 年 10 月 22 日以后结束。Google Play 强制执行此要求,以确保在新版本可用时,用户可以无缝升级应用。如果您使用 Google Play 应用签名,则 Google 可确保您的应用正确签署,并能够在它们的整个生命周期内接收更新。
5.
从您的构建文件中移除签署信息
在您创建签署配置时,Android Studio 会以纯文本形式将您的签署信息添加到模块的 build.gradle
文件中。如果您是团队协作开发或者将您的代码开源,那么您应当将此敏感信息从构建文件中移出,以免被其他人轻易获取。为此,您应创建一个单独的属性文件来存储安全信息并按以下步骤操作,在您的构建文件中引用该文件:
- 创建一个签署配置,并将其分配至一个或多个构建类型。这些说明假设您已经按照上面配置构建流程以自动签署您的 APK 部分所述,为发布构建类型配置了一个签署配置。
- 在项目的根目录下创建一个名为
keystore.properties
的文件。此文件应当包含您的签署信息,如下所示:
storePassword=myStorePassword
keyPassword=mykeyPassword
keyAlias=myKeyAlias
storeFile=myStoreFileLocation - 在模块的
build.gradle
文件中,于android {}
块的前面添加用于加载keystore.properties
文件的代码。
...
// Create a variable called keystorePropertiesFile, and initialize it to your
// keystore.properties file, in the rootProject folder.
def keystorePropertiesFile = rootProject.file("keystore.properties")
// Initialize a new Properties() object called keystoreProperties.
def keystoreProperties = new Properties()
// Load your keystore.properties file into the keystoreProperties object.
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
...
}注:您可以选择将
keystore.properties
文件存储在其他位置(例如,存储在模块文件夹中而不是项目的根文件夹中,或者如果您使用持续集成工具,也可以存储在构建服务器上)。在这种情况下,您应当修改上面的代码,以便使用实际keystore.properties
文件的位置正确初始化keystorePropertiesFile
。 - 您可以使用语法
keystoreProperties['propertyName']
引用存储在keystoreProperties
中的属性。修改模块build.gradle
文件的signingConfigs
块,以便使用此语法引用存储在keystoreProperties
中的签署信息。
android {
signingConfigs {
config {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
}
...
} - 打开 Build Variants 工具窗口并确保已选择发布构建类型。
- 点击 Build > Build APK 以构建您的发布构建,并确认 Android Studio 已在模块的
build/outputs/apk/
目录中创建一个签署的 APK。
由于您的构建文件不再包含敏感信息,您现在可以将其包含在源控制中或者上传到共享的代码库。务必保证 keystore.properties
文件的安全。您可能需要将其从您的源控制系统中移除。