3

I'm familiar with building large applications using make, but now I have begun using Android Studio and I want to understand how to do things I already do in a Makefile.

Here are a example that might help you frame an answer:

Makefile example: (minimalist)

INK=inkscape
INKFLAGS=--export-area-page

# Resolve *.png dependencies
drawable-mdpi/%.png: %.svg
         $(INK) $< --export-png=$@ -w 48 -h 48 $(INKFLAGS) 

drawable-hdpi/%.png: %.svg
         $(INK) $< --export-png=$@ -w 72 -h 72 $(INKFLAGS) 

drawable-xdpi/%.png: %.svg
         $(INK) $< --export-png=$@ -w 96 -h 96 $(INKFLAGS) 

More simple example:

drawable-mdpi/ic_launcher.png: ic_launcher.svg
         inkscape ic_launcher.svg --export-png=ic_launcher.png -w 48 -h 48 --export-area-page 

drawable-hdpi/ic_launcher.png: ic_launcher.svg
         inkscape ic_launcher.svg --export-png=ic_launcher.png -w 72 -h 72 --export-area-page 

How to do that in Gradle?

I want to resolve external dependencies such as mentioned in the above example. Actually I'm doing it via 'make', but i want to completely remove this extra step.

rnrneverdies
  • 15,243
  • 9
  • 65
  • 95
  • Gradle by default compiles all drawable media from the "drawable" folder in your android project. It also recognises subfolders such as drawable-hdpi and drawable-mdpi automatically and will use those if appropriate and available to look up appropriate images for a resolution. There is a `dependencies` tag in the build.gradle file but from what I know it's mainly used to add externals JARS from the project or like Maven, to supply an address to an external repository to download a library for you. Hope it helps you on your way a bit. – G_V Dec 18 '14 at 13:09
  • @G_V i know that, i want to resolve external dependencies such as mentioned in my example. Is unproductive exporting each image manually when is modified. In fact currently i'm doing it using 'make', but i want to completely remove this extra step. – rnrneverdies Dec 19 '14 at 01:15
  • I can imagine, I prescale everything down in code on a background thread myself, then cache what I need for as long as I need it. Works well enough unless you have hundreds of large drawables, in which case the scaling itself still won't slow down the app much but the garbage collector does. I can't really help you but perhaps Gradle's [recommended books](https://www.gradle.org/books) are of more use. – G_V Dec 19 '14 at 11:17

1 Answers1

3

It is possible to run external commands from Grandle and integrate those into your build process. My example runs inkscape.exe on Windows and defines its parameters in the build script, you can also just run a shell script this way.

The following code goes into the app\build.gradle file. Task convertDrawable is written in Groovy syntax and accomplishes the following (tl;dr it is an implementation of your "simple example"):

  • It looks through all the *.svg files in a custom folder art/drawable
  • Within each of those *.svg files, looks through all the drawable-* folders in your resources folder
  • Based on drawable-* folder name, determine the target resolution.
  • Then calls inkscape.exe to convert each *.svg to *.png with the required size.

Code:

task convertDrawables() {
    def ink =  'C:\\Program Files (x86)\\Inkscape\\inkscape.exe'

    // look for *.svg files in app/src/art/drawable folder
    new File('app\\src\\art\\drawable').eachFileMatch(~/.*\.svg/) { file ->
        // look for destination folders
        new File('app\\src\\main\\res').eachFileMatch(~/drawable-.*/) { outputDir ->

            // define size based on folder name
            def size = ''
            switch (outputDir.getAbsolutePath()) {
                case ~/.*-ldpi/:
                    size = '36'
                    break
                case ~/.*-mdpi/:
                    size = '48'
                    break
                case ~/.*-hdpi/:
                    size = '72'
                    break
                case ~/.*-xhdpi/:
                    size = '96'
                    break
                case ~/.*-xxhdpi/:
                    size = '144'
                    break
                case ~/.*-xxxhdpi/:
                    size = '192'
                    break
            }
            def cmd = ink + ' ' + file.getCanonicalPath() + ' --export-png=' + outputDir.getAbsolutePath() + '\\ic_launcher2.png -w ' + size + ' -h ' + size + ' --export-area-page'
            def process = cmd.execute();
            process.waitFor();
        }
    }
}


// make sure the convertDrawable task is executed somewhere in the make process
gradle.projectsEvaluated {
    preBuild.dependsOn(convertDrawable)
}

Here are the resources I used:

Community
  • 1
  • 1
chrki
  • 6,143
  • 6
  • 35
  • 55