android 拷贝文件到apk里,在Android Gradle proj中复制APK文件

在Android Gradle proj中复制APK文件

我试图将自定义任务添加到我的Android项目的build.gradle中,以将最终的APK和Proguard的publish复制到另一个目录中。 我的任务取决于assemble任务:

task publish(dependsOn: 'assembleDevDebug') << {

description 'Copies the final APK to the release directory.'

...

}

我可以根据文档查看如何使用标准publish任务类型进行文件复制:

task(copy, type: Copy) {

from(file('srcDir'))

into(buildDir)

}

但是,前提是您知道要复制的文件的名称和位置。

如何查找作为publish任务的一部分而构建的APK文件的确切名称和位置? 这可以作为财产使用吗? 感觉好像我应该能够将文件声明为任务的输入,并将其声明为assemble任务的输出,但我的Gradle-fu不够强大。

我有一些自定义逻辑将版本号注入APK文件名,因此我的publish任务不能只是假设默认名称和位置。

6个解决方案

27 votes

如果可以获取与devDebug关联的变量对象,则可以使用getOutputFile()查询它。

因此,如果您想发布所有变体,您将像这样:

def publish = project.tasks.create("publishAll")

android.applicationVariants.all { variant ->

def task = project.tasks.create("publish${variant.name}Apk", Copy)

task.from(variant.outputFile)

task.into(buildDir)

task.dependsOn variant.assemble

publish.dependsOn task

}

现在您可以致电gradle publishAll,它将发布您所有的变体。

映射文件的一个问题是Proguard任务无法使您获得文件位置的信息,因此您目前无法对其进行查询。 我希望能解决这个问题。

Xavier Ducrohet answered 2020-08-10T08:00:42Z

9 votes

下面的代码是我用来将apk和proguard映射归档到带有'release'构建类型的每个变体的zip文件中的代码:

def releasePath = file("${rootDir}/archive/${project.name}")

def releaseTask = tasks.create(name: 'release') {

group 'Build'

description "Assembles and archives all Release builds"

}

android.applicationVariants.all { variant ->

if (variant.buildType.name == 'release') {

def build = variant.name.capitalize()

def releaseBuildTask = tasks.create(name: "release${build}", type: Zip) {

group 'Build'

description "Assembles and archives apk and its proguard mapping for the $build build"

destinationDir releasePath

baseName variant.packageName

if (!variant.buildType.packageNameSuffix) {

appendix variant.buildType.name

}

if (variant.versionName) {

version "${variant.versionName}_${variant.versionCode}"

} else {

version "$variant.versionCode"

}

def archiveBaseName = archiveName.replaceFirst(/\.${extension}$/, '')

from(variant.outputFile.path) {

rename '.*', "${archiveBaseName}.apk"

}

if (variant.buildType.runProguard) {

from(variant.processResources.proguardOutputFile.parent) {

include 'mapping.txt'

rename '(.*)', "${archiveBaseName}-proguard_\$1"

}

}

}

releaseBuildTask.dependsOn variant.assemble

variant.productFlavors.each { flavor ->

def flavorName = flavor.name.capitalize()

def releaseFlavorTaskName = "release${flavorName}"

def releaseFlavorTask

if (tasks.findByName(releaseFlavorTaskName)) {

releaseFlavorTask = tasks[releaseFlavorTaskName]

} else {

releaseFlavorTask = tasks.create(name: releaseFlavorTaskName) {

group 'Build'

description "Assembles and archives all Release builds for flavor $flavorName"

}

releaseTask.dependsOn releaseFlavorTask

}

releaseFlavorTask.dependsOn releaseBuildTask

}

}

}

它创建如下任务:

发布-组装和存档所有发布版本

releaseFree-组装和存档所有发行版本,以释放Free

releaseFreeRelease-为FreeRelease构建和存档apk及其proguard映射

releasePaid-组装和存档所有发布版本,以实现Paid Paid

releasePaidRelease-为PaidRelease构建和存档apk及其proguard映射

archive / projectName / packageName-buildType-versionName_versionCode.zip的内容为:

packageName-buildType-versionName_versionCode.apk

packageName-buildType-versionName_versionCode-proguard_mapping.txt

Ladios Jonquil answered 2020-08-10T08:01:42Z

6 votes

这就是每当Proguard运行时我如何复制mappings.txt

tasks.whenTaskAdded { task ->

if (task.name.startsWith("proguard")) {//copy proguard mappings

task << {

copy {

from buildDir.getPath() + "/proguard"

into '../proguard'

include '**/mapping.txt'

}

println "PROGUARD FILES COPIED"

}

}

}

martinpelant answered 2020-08-10T08:02:02Z

6 votes

我在这里有一些很好的建议,但是也很难按照我的意愿完成。 这是我的最终版本:

def archiveBuildTypes = ["distribute"];

def archiveFlavors = ["googleplay"]

android.applicationVariants.all { variant ->

if (variant.buildType.name in archiveBuildTypes) {

variant.productFlavors.each { flavor ->

if (flavor.name in archiveFlavors) {

def taskSuffix = variant.name.capitalize()

def version = "${android.defaultConfig.versionCode} (${android.defaultConfig.versionName})" // assumes that versionName was especified here instead of AndroidManifest.xml

def destination = "${rootDir}/${project.name}/archive/${version}"

def assembleTaskName = "assemble${taskSuffix}"

if (tasks.findByName(assembleTaskName)) {

def copyAPKTask = tasks.create(name: "archive${taskSuffix}", type:org.gradle.api.tasks.Copy) {

description "Archive/copy APK and mappings.txt to a versioned folder."

from ("${buildDir}") {

include "**/proguard/${flavor.name}/${variant.buildType.name}/mapping.txt"

include "**/apk/${variant.outputFile.name}"

}

into destination

eachFile { file->

file.path = file.name // so we have a "flat" copy

}

includeEmptyDirs = false

}

tasks[assembleTaskName].finalizedBy = [copyAPKTask]

}

}

}

}

}

saulobrito answered 2020-08-10T08:02:22Z

4 votes

def publish = project.tasks.create("publishAll")// publish all task

applicationVariants.all { variant ->

if (variant.buildType.name.equals("release")) {// Only Release

File outDir = file("//192.168.4.11/Android/Release")

File apkFile = variant.outputs[0].outputFile

File mapFile = variant.mappingFile

def task = project.tasks.create("publish${variant.name.capitalize()}Apk", Copy)

task.from apkFile, mapFile

task.into outDir

task.rename "mapping.txt", "${apkFile.name.substring(0, apkFile.name.length() - 3)}mapping.txt"// Rename mapping.txt

task.doLast{

println ">>>publish ${variant.name} success!" +

"\ndir: ${outDir}" +

"\napk: ${apkFile.name}"

}

task.dependsOn variant.assemble

publish.dependsOn task

}

}

ipcjs answered 2020-08-10T08:02:38Z

0 votes

通常,android插件会将apks放在APP / build / apk目录中。

因此,运行assembleDebug,然后运行ls APP/build/apk,您应该看到:

APP调试未对齐.apk

APP发行不对齐.apk

APP-release-unsigned.apk

APP-release.apk等等

cbrulak answered 2020-08-10T08:03:19Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值