在我的Android Studio / gradle版本中,我尝试自动生成应用图标。生成图标图像(PNG)的任务正在正确的时间运行,但图像在消耗它的任务运行之前被删除。
这是我已添加到app/build.gradle
的简化版本,说明了问题:
task createIcon(type:Exec) {
def outdir =
new File("$buildDir/intermediates/res/merged/debug/drawable-ldpi/")
outputs.dir(outdir)
if (!outdir.exists()) {
outdir.mkdirs()
}
def svg = 'src/images/ic_launcher.svg'
inputs.source(new File(svg))
def png = new File(outdir, "ic_launcher.png")
outputs.file(png)
commandLine "$workingDir/svgToPng.sh", svg, png
}
tasks.whenTaskAdded{ t ->
if(t.name.equals("generateDebugAssets")){
t.dependsOn createIcon
}
}
如果我运行./gradlew clean
然后./gradlew assembleDebug
,我可以看到我的createIcon
任务的输出文件," app / build / intermediates / res / merged / debug /drawable-ldpi/ic_launcher.png"已创建,然后很快删除。我从gradlew获得以下输出:
:app:preBuild UP-TO-DATE
:app:preDebugBuild UP-TO-DATE
...
Bitmap saved as: /home/laurence/src/foo/app/build/intermediates/res/merged/debug/drawable-ldpi/ic_launcher.png
:app:generateDebugAssets
:app:mergeDebugAssets
:app:generateDebugResValues UP-TO-DATE
:app:generateDebugResources
:app:mergeDebugResources
:app:processDebugManifest
:app:processDebugResources
/home/laurence/src/foo/app/build/intermediates/manifests/full/debug/AndroidManifest.xml:13:23-44 : AAPT: No resource found that matches the given name (at 'icon' with value '@drawable/ic_launcher').
:app:processDebugResources FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:processDebugResources'.
> com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/home/laurence/.local/android-sdks/build-tools/23.0.2/aapt'' finished with non-zero exit value 1
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
您可以看到任务:app:processDebugResources
失败,因为aapt
声称它无法找到@drawable/ic_launcher
(我android:icon
中AndroidManifest.xml
的值)它应该对应于我生成PNG的地方。
请注意,我已经确认PNG的生成不仅来自"位图保存为"在控制台输出中行,但也可以在构建期间查看目标目录。文件闪烁存在然后消失片刻。
如果我第二次运行./gradlew assembleDebug
构建成功,那就更奇怪了!
如何阻止我生成的PNG被删除,并确保processDebugResources
可以看到它而无需运行我的构建两次?
答案 0 :(得分:1)
我认为您的问题是您正在configuration
阶段而不是execution
阶段创建目录(更多信息here)
请改为尝试:
task createIcon(type:Exec) {
def svg = 'src/images/ic_launcher.svg'
def outdir = file("$buildDir/intermediates/res/merged/debug/drawable-ldpi/")
def png = new File(outdir, "ic_launcher.png")
inputs.file(svg)
outputs.dir(outdir)
commandLine "$workingDir/pngToSvg.sh", png, svg
doFirst {
outdir.mkdirs()
}
}
答案 1 :(得分:1)
事实证明,有两个较小的错误,一个大错误。
一个小错误是pointed out by Lance Java:目录创建是在配置阶段完成的,而不是执行阶段。另一个小错误是它应该与generateDebugResources
相关联,而不是generateDebugAssets
。然而,修复这些较小的错误并没有解决问题。
最大的错误是文件被写入另一个任务写入的子树。我这样做是因为我不知道如何获取包含在程序集中的文件,但这不是正确的方法,因为写入该子树的其他任务有时会踩到文件(取决于执行任务的顺序),导致它们“消失”。
要解决所有这些问题,第一步是为我们的任务选择一个不会干扰其他任务的新输出目录:
def fromSvgDir = file("$buildDir/generated/fromSvg/")
然后,我们将此srcDirs
添加到res
文件顶部附近现有android
块中的build.gradle
:
sourceSets {
main {
res {
srcDirs += fromSvgDir
}
}
}
最后,让我们的任务使用该目录,并修复其他两个错误:
task createIcon(type:Exec) {
def outdir = file("$fromSvgDir/drawable-ldpi/")
outputs.dir(outdir)
doFirst {
outdir.mkdirs()
}
def svg = file('src/images/ic_launcher.svg')
inputs.source(svg)
def png = file("$outdir/ic_launcher.png")
outputs.file(png)
commandLine "$workingDir/svgToPng.sh", svg, png
}
tasks.whenTaskAdded{ t ->
if(t.name.equals("generateDebugResources")){
t.dependsOn createIcon
}
}
这是可靠的,并且还具有以下优点:生成的PNG将像非生成的PNG一样通过PNG计算器。