2016-03-26 10 views
1

Android Studio/gradle derlememde, uygulama simgemi otomatik olarak oluşturmaya çalışıyorum. Simge görüntüsünü (PNG) üreten görev, doğru zamanda çalıştırılıyor, ancak görüntü tüketen görev çalışmaya başlamadan önce siliniyor.Ara sıra dosyalarımın daha sonra görevleri tüketmeden önce silmeyi nasıl engellerim?

Bu benim sorunu göstermektedir benim app/build.gradle eklediğiniz ne basitleştirilmiş bir versiyonudur: Ben ./gradlew clean ve sonra ./gradlew assembleDebug çalıştırırsanız

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 
     } 
} 

, görebildiğim benim createIcon görevin çıktı dosyası, "app/build/intermediates/res/merged/debug/drawable-ldpi/ic_launcher.png" oluşturuldu ve daha sonra çok geçmeden silindi. Ben gradlew aşağıdaki çıktıyı almak:

: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 

Sen aapt iddialar o @drawable/ic_launcher bulamadığından görev :app:processDebugResources başarısız olduğunu görebilirsiniz (içinde android:icon değerini benim AndroidManifest.xml) yerine karşılık gelmelidir nerede PNG'yi üretiyorum.

PNG'nin yalnızca konsol çıktısında "Bitmap olarak kaydedildi" satırından değil, yapı sırasında hedef dizini izleyerek oluşturulduğunu da doğruladım. Dosya varolmaya başlar ve daha sonra bir an ortadan kaybolur.

Hatta bundan daha da kötüsü, ./gradlew assembleDebug'u ikinci kez çalıştırırsam, yapı başarılı olur!

Oluşturulmuş PNG'nin silinmesini nasıl engellerim ve yapmamı iki kez çalıştırmaya gerek kalmadan processDebugResources'un görmesini sağlarım?

cevap

1

O tane buldum iki küçük hatalar ve büyük bir böcek. Bir küçük hata, pointed out by Lance Java idi: dizin oluşturma, yürütme aşamasından ziyade, yapılandırma aşamasında gerçekleştiriliyordu. Diğer küçük hata, bu generateDebugAssets değil generateDebugResources, bağlı olması gerektiği idi. Ancak, bu küçük hataların giderilmesi sorunu çözmedi.

Büyük hata, dosyaların başka bir göreve yazılmakta olan bir alt ağaca yazılıyor olmasıydı. Bunu yapıyordum çünkü montajda yer almak için alınan dosyaları başka nasıl alacağımı bilmiyordum, ancak bu alt-ağacın üzerine yazılan diğer görevler bazen durduracak doğru bir yaklaşım değildi. dosyalar (görevlerin hangi sırayla yapıldığına bağlı olarak), "yok olma" durumuna neden olur.Sonra içinde res için srcDirs eklemek bu

def fromSvgDir = file("$buildDir/generated/fromSvg/") 

:

bu sorunların saptamak için ilk adım diğer görevler engel olmaz bizim görev için yeni bir çıkış dizin seçmektir build.gradle dosyanın üstüne yakın mevcut android blok:

sourceSets { 
    main { 
     res { 
      srcDirs += fromSvgDir 
     } 
    } 
} 

Son olarak, görevimiz bu iki diğer hataları düzeltmek de o dizini kullanın ve var:

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 
     } 
} 

Bu, güvenilir şekilde çalışır ve ayrıca oluşturulan PNG'lerin, PNG kırıcıyı, oluşturulmamış PNG'ler gibi geçirmesi avantajına sahiptir.

+1

Proje nesnesi yerine [dosya] (https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html#file (java.lang.Object)) kolaylık yöntemlerini tercih etmelisiniz Bir dosya nesnesini kendiliğinden açabilirsiniz. Örneğin, from 'svgDir = dosya (" $ buildDir/generated/fromSvg/")' yerine 'from defsvgDir = yeni dosya (buildDir," created/fromSvg/")' –

+0

@LanceJava Teşekkürler. Ben (ve groovy) kürek için oldukça yeni ve henüz en iyi uygulamalara aşina değilim. Cevabınızı önerinize göre güncelledim. –

1

Ben senin sorunu yerine bu deneyin execution faz (daha fazla bilgi here)

yerine configuration fazda dizin oluşturma olduğunu düşünüyorum:

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() 
    } 
} 
+0

Teşekkürler. Bu kesinlikle bir hataya benziyor, aslında sorunumu çözmedi. Biraz daha güldükten sonra sonunda cevap olarak gönderdiğim bir çözüm buldum. –

İlgili konular