gradlew 命令生成apk、aab包
其实构建应用程序包就几个命令:
### 生成AAB:
gradlew bundleRelease #输出到[project]/build/outputs/bundle/release/下
gradlew bundleDebug
### 生成APK:
gradlew assembleRelease
gradlew assembleDebug
### 清楚gradle缓存
gradlew cleanBuildCache
接下来看下如何在项目中使用本地下载的sdk
local.properties使用以及Gradle文件、Manifests文件如何使用local.properties配置的值
先看下一般local.properties的内容:
sdk.dir
打包构建时,项目会读取local.properties文件中的sdk.dir配置构建时使用的SDK,所以sdk.dir配置是必要的,具体目录看你安装的SD目录位置.
channel
channel我是用来区分渠道的,一般在AndroidManifests.xml会有以下一段配置:
<meta-data android:name="DCLOUD_STREAMAPP_CHANNEL" android:value="包名|appid||${channel}"/>
其中channel就是要动态配置的值,这个值需要在build.gradle中先读取配置:
配置后就可以在AndroidManifests.xml中读取了。
outputDir
如果有需要修改打包后输出目录路径以及修改文件名就在build.gradle文件这样做:
android {
...
applicationVariants.all { variant ->
variant.outputs.all { output ->
def apkDir = rootProject.file(properties.getProperty("outputDir"));
if (!apkDir.exists()) {
apkDir.mkdirs()
}
variant.packageApplicationProvider.get().outputDirectory = apkDir // 指定apk的输出位置
def packageType = properties.getProperty("packageType");
def channel = properties.getProperty("channel");
def version = properties.getProperty("version");
def name = "zh_${channel}_${version}";
if (buildType.name == 'debug') {
name = name + "_dev";
}
output.outputFileName = "${name}.${packageType}"; // 指定输出文件名
}
}
}
以上的配置只针对打包apk有效,修改打包aab文件输出目录的方法暂时没找到,欢迎各位大佬指点!
打包aab一般是输出到[project]/build/outputs/bundle/release/
,可以自己验证下对不对。
最后在外部构建机一般会新建一个local.properties(一般不会上传到代码仓库):
echo 'set local.properties'
echo 'sdk.dir=sdk目录' >> local.properties
echo 'outputDir=输出目录' >> local.properties
echo 'channel=渠道' >> local.properties
echo 'version=版本 >> local.properties
echo 'packageType=apk or aab' >> local.properties
- 补充一种情况,上传google应用商店是上传aab包,这是google console会对包进行二次签名,会导致报名和对应的秘钥、签名证书不一致等,所以这时候会有一个需求:打包apk包使用的包名和aab包名不一致,这时候build.gradle可以这样配置(可能这样用不太合适,因为这里用来扩展渠道的):
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
android {
compileSdkVersion 33
defaultConfig {
applicationId "包名1"
flavorDimensions "App" #必须的,目前就是两个渠道
}
productFlavors {
dev {
dimension "App" #必须的
// 每个环境包名不同
applicationId "包名1"
// 动态修改 常量 字段
buildConfigField "String", "ENVIRONMENT", '"dev"'
// 修改 AndroidManifest.xml 里渠道变量
manifestPlaceholders = [
UMENG_CHANNEL_VALUE: "dev",
name: "包名1",
channel: properties.getProperty("channel")
]
}
prod {
dimension "App" #必须的
applicationId "包名2"
buildConfigField "String", "ENVIRONMENT", '"prod"'
manifestPlaceholders = [
# 以下可以在AndroidManifest.xml中使用
UMENG_CHANNEL_VALUE: "prod",
name: "包名2"
channel: properties.getProperty("channel")
]
}
}
}
配置完以上后会报错:
A problem was found with the configuration of task ':project:createReleaseApkListingFileRedirect' (type 'ListingFileRedirectTask').
In plugin 'com.android.internal.version-check' type 'com.android.build.gradle.internal.tasks.ListingFileRedirectTask' property 'listingFile' specifies file 'xxx/xxx' which doesn't exist.
一种方法是把之前配置的修改应用程序包建构输出的目录, 但这不是最优的解决方案,具体参考Gradle ListingFileRedirectTask 引发的打包问题,在build.gradle最后加上:
tasks.whenTaskAdded {task ->
if (task.name.contains("ReleaseApkListingFileRedirect")) { // 过滤release
task.enabled = false
}
}
其中AndroidManifest.xml中的:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="可以随意配置">
</manifest>
使用命令gradlew bundleDevRelease
或 gradlew bundleProRelease
构建后会自动配置对应的包名,gradlew bundleProRelease
打包出来的路径如下: