Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Level Up your Android Build - DevoxxUK 2015
Search
Volker
June 19, 2015
Technology
120
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Level Up your Android Build - DevoxxUK 2015
Slides from my talk at DevoxxUK.
Volker
June 19, 2015
Other Decks in Technology
See All in Technology
日本語に強いオープンな大規模言語モデル「LLM-jp」
odashi
4
1.1k
1つのリクエストを追って理解する - llm-dのP/D分離
akhino
1
160
宣言型部分更新は何を解決しどこへ向かうのか
shuta13
1
450
『SAR衛星データ解析入門』のご紹介とその応用
syuchimu
0
120
AI導入は済んだ。次は統制を作り替える番だ_AI×開発組織 Summit 2026
techtekt
PRO
0
210
大型犬好きによるPugの紹介
yamanoku
1
160
スキマバイトという雇用形態は存在しないので、雇用期間1日のアルバイト契約を事業者とワーカーが結ぶ手続きを支えるのがタイミーなんです
akitoshiga
0
200
Classmethod Company Deck
satoshi7
1
680
ストレスなくAIと付き合いたい!こんなときどうしてる?
namiki64
3
490
QA4AI 2026-Oct 生成AI時代の品質保証
tokuty
1
860
スプシの手作業からの解脱 ~更新はClaude Codeに、見せ方と使い方はGASアプリに任せる~
kentarofujii
0
150
JAWSUG TOHOKU 青森支部 「LoGoチャット」のAWS移行で 乗り越えたこと
taketakekaho
0
330
Featured
See All Featured
Done Done
chrislema
187
17k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
58k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
540
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
31k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
GraphQLとの向き合い方2022年版
quramy
50
15k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
50
10k
Rails Girls Zürich Keynote
gr2m
96
14k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
330
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
410
Transcript
@devisnik #AndroidBuild Level Up Your Android Build Volker Leck, Novoda,
Berlin
@devisnik #AndroidBuild Getting started
@devisnik #AndroidBuild app/build.gradle apply plugin: 'com.android.application' android { compileSdkVersion 22
buildToolsVersion '22.2.0' defaultConfig { ... } buildTypes { release { ... } } } dependencies { ... }
@devisnik #AndroidBuild Relevant Build Files ├── app │ └── build.gradle
├── build.gradle ├── gradle │ └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── local.properties └── settings.gradle
@devisnik #AndroidBuild Gradle wrapper $ ./gradlew tasks
@devisnik #AndroidBuild Gradle wrapper $ gw clean ass
@devisnik #AndroidBuild Using a Gradle plugin /build.gradle buildscript { repositories
{ jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.2.3' classpath 'com.novoda:gradle-android-command-plugin:1.4.0' } } /app/build.gradle apply plugin: 'com.novoda.android-command' $ gw runDebug
@devisnik #AndroidBuild Dependencies dependencies { compile 'com.google.guava:guava:18.0' testCompile 'junit:junit:4.12' testCompile
'org.mockito:mockito-core:1.9.5' }
@devisnik #AndroidBuild Dependencies apply plugin: 'com.neenbedankt.android-apt' dependencies { apt 'com.google.dagger:dagger-compiler:2.0'
compile 'com.google.dagger:dagger:2.0' compile 'com.google.guava:guava:18.0' testCompile 'junit:junit:4.12' testCompile 'org.mockito:mockito-core:1.9.5' }
@devisnik #AndroidBuild Dependencies apply plugin: 'com.neenbedankt.android-apt' dependencies { apt 'com.google.dagger:dagger-compiler:2.0'
compile 'com.google.dagger:dagger:2.0' compile 'com.google.guava:guava:18.0' paidCompile project(':lvl') testCompile 'junit:junit:4.12' testCompile 'org.mockito:mockito-core:1.9.5' }
@devisnik #AndroidBuild Proguard
@devisnik #AndroidBuild Proguard buildTypes { release { minifyEnabled true shrinkResources
true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard.cfg' } } proguard.cfg #Dagger2 -dontwarn dagger.shaded.auto.common.** -dontwarn dagger.internal.codegen.** -keepattributes Signature
@devisnik #AndroidBuild Archive Release ext.VERSION_NAME=1.0.0 ... task archiveRelease(type: Copy) {
from 'build/outputs/apk', 'build/outputs/' into "releases/${VERSION_CODE}" include('android-release.apk', 'mapping/**') rename ('android-release.apk', "${APP_NAME}_${BUILD_DATE}_${VERSION_NAME}_${VERSION_CODE}.apk") }
@devisnik #AndroidBuild Udacity course
@devisnik #AndroidBuild First Success
@devisnik #AndroidBuild Scaling up • re-use • testing • quality
assurance • continuous integration • push-button release
@devisnik #AndroidBuild Re-use - Core project gradle init --type java-library
dependencies { compile project(':model') }
@devisnik #AndroidBuild gradle init --type java-library dependencies { compile project(':model')
} gradle init --type groovy-library def url = new URL('https://api.github.com/users/devisnik/starred') def json = new JsonSlurper().parseText(url.text) println json*.name Re-use - Playground project
@devisnik #AndroidBuild Testing - Integration Tests in Core sourceSets {
integrationTest { java { srcDir 'src/integrationtest/java' } resources { srcDir 'src/integrationtest/resources' } compileClasspath += sourceSets.main.runtimeClasspath } } task integrationTest(type: Test) { testClassesDir = sourceSets.integrationTest.output.classesDir classpath += sourceSets.integrationTest.runtimeClasspath }
@devisnik #AndroidBuild Keeping Up To Date apply plugin: 'com.github.ben-manes.versions' $
gw dependencyUpdates The following dependencies have later milestone versions: - com.fasterxml.jackson.core:jackson-annotations [2.1.2 -> 2.6.0- rc1] - com.fasterxml.jackson.core:jackson-core [2.1.1 -> 2.6.0-rc1] - com.fasterxml.jackson.core:jackson-databind [2.1.2 -> 2.6.0-rc1] - com.github.kevinsawicki:http-request [4.0 -> 9.9] - joda-time:joda-time [2.3 -> 2.8] - org.mockito:mockito-core [1.9.0 -> 2.0.8-beta] Generated report file build/dependencyUpdates/report.txt
@devisnik #AndroidBuild Code Quality Tools apply plugin: 'checkstyle' task checkstyleMain(
type: Checkstyle) { description 'Checks whether code complies with coding rules.' ignoreFailures !project.failFastOnError ... doLast { if (project.hasProperty('checkstyle.html')) { ant.xslt(in: reports.xml.destination, style: file("$rulesDir/checkstyle/noframes-sorted. xsl"), out: new File(reports.xml.destination.parent, name - 'checkstyle' + '.html')) } } }
@devisnik #AndroidBuild Code Quality Tools apply plugin: 'checkstyle' task checkstyleMain(type:
Checkstyle) { description 'Checks whether code complies with coding rules.' ignoreFailures !project. failFastOnError ... doLast { if (project.hasProperty(' checkstyle.html')) { ant.xslt(in: reports.xml.destination, style: file("$rulesDir/checkstyle/noframes-sorted. xsl"), out: new File(reports.xml.destination.parent, name - 'checkstyle' + '.html')) } } } $ gw checkstyleMain -PfailFastOnError -Pcheckstyle.html
@devisnik #AndroidBuild Code Quality Tools apply plugin: 'checkstyle' task checkstyleMain(type:
Checkstyle) { description 'Checks whether code complies with coding rules.' ignoreFailures !project.failFastOnError ... doLast { if (project.hasProperty('checkstyle.html')) { ant.xslt(in: reports.xml.destination, style: file("$rulesDir/checkstyle/noframes-sorted. xsl"), out: new File(reports.xml.destination.parent, name - 'checkstyle' + '.html')) } } }
@devisnik #AndroidBuild Continuous Integration System.getenv("...") Jenkins BUILD_NUMBER Travis TRAVIS_BUILD_NUMBER
@devisnik #AndroidBuild Updating the Android SDK apply plugin: 'android-sdk-manager' $
gw assembleDebug Android SDK not found. Downloading... > Configuring > 1/5 projects > :android SDK extracted at '/Users/leck/.android-sdk'. Writing to local. properties. Build tools 21.1.2 missing. Downloading... > Configuring > 2/5 projects Platform tools missing. Downloading... Compilation API android-21 missing. Downloading… ...
@devisnik #AndroidBuild Connected Tests on CI task filterTestDevices << {
com.android.builder.testing. ConnectedDeviceProvider.metaClass .getDevices = { localDevices .findAll { it.iDevice.online } .findAll { !it.getProperty('ro.build.characteristics') ?.toLowerCase()?.contains('tablet') } .unique { it.apiLevel } } }
@devisnik #AndroidBuild Connected Tests on CI afterEvaluate { project.tasks.findAll {
it.name.startsWith('connectedAndroidTest') }*.dependsOn filterTestDevices }
@devisnik #AndroidBuild Releasing from CI • update Version • commit
changes • upload to Stores
@devisnik #AndroidBuild Release from CI - Versioning def versionFile =
file('version.properties') Version version = Version.read(versionFile) task incrementVersion << { Version.increment(versionFile) }
@devisnik #AndroidBuild Release from CI - Versioning def versionFile =
file('version.properties') Version version = Version.read(versionFile) task incrementVersion << { Version.increment(versionFile) } buildSrc └── src └── main └── groovy └── Version.groovy
@devisnik #AndroidBuild Release from CI - git buildscript { dependencies
{ classpath 'org.ajoberstar:grgit:1.1.0' } } ext { git = org.ajoberstar.grgit.Grgit.open( rootProject.file('.')) } def sha = git.head().abbreviatedId git.add 'version.properties' git.commit(message: "Bumping version to $VERSION_CODE") git.push()
@devisnik #AndroidBuild Publishing - Google Play play-publisher-plugin bootstrapReleasePlayResources publishApkRelease publishListingRelease
publishRelease
@devisnik #AndroidBuild Tips & Tricks
@devisnik #AndroidBuild Shared Build Logic share common configuration data via
root build.gradle File rules(String relativeFilePath) { file("shared/rules/$relativeFilePath") } app/build.gradle: findbugs { excludeFilter rules('findbugs/exclude.xml') ... }
@devisnik #AndroidBuild Shared Build Logic share common dependencies via root
build.gradle ext { guava_lib = 'com.google.guava:guava:18.0' ... testing_libs = [junit_lib, assertJ_lib] } use it in sub-projects via: dependencies { compile guava_lib ... testCompile testing_libs }
@devisnik #AndroidBuild Shared Build Logic android { … buildTypes {
debug { buildConfigField 'String', 'TAG' ,'"DEBUG_TAG"' } release { buildConfigField 'String', 'TAG' ,'"RELEASE_TAG"' } } } android.buildTypes.all { ext.tag = { tag -> buildConfigField 'String', 'TAG', '"'+ tag +'"' } } buildTypes { debug { tag 'DEBUG_TAG' } release { tag 'RELEASE_TAG' } }
@devisnik #AndroidBuild Library Shrinking dependencies { classpath 'net.sf.proguard:proguard-gradle:4.11' } ...
task shrinkGuava(type: proguard.gradle.ProGuardTask) { injars configurations.injar.files libraryjars configurations.libjar.files outjars file("build/libs/guava_${guavaVersion}_base.jar") configuration 'guava.proguard' } guava.proguard: -dontoptimize -dontobfuscate -keep public class com.google.common.base.** { public *; }
@devisnik #AndroidBuild Auto Login task autoLogin(type: com.novoda.gradle.command.Input) { script {
2.times { text 'bob' enter() } enter() } }
@devisnik #AndroidBuild Sync images task syncPhotos(type: com.novoda.gradle.command.Files) { deviceId {
def moto = android.command.devices().find { it.brand() == 'motorola' } moto.id } script { def backupDir = mkdir 'motoPhoto' list('/sdcard/DCIM/Camera/').findAll { image -> !new File(backupDir.path, image.name).exists() }.each { image -> pull image.path + image.name, backupDir.path } } }
@devisnik #AndroidBuild Sqlite Access sqliteAccess { migrationsDir 'src/main/assets/migrations' packageName 'com.novoda.sqliteprovider.demo.simple'
generator { database, basedir -> def access = access(database) // adjust access model as needed generateClass(file('code.template'), access, 'DB', packageName, basedir) } }
@devisnik #AndroidBuild Sqlite Access sqliteAccess { migrationsDir 'src/main/assets/migrations' packageName 'com.novoda.sqliteprovider.demo.simple'
generator { database, basedir -> def access = access(database) // adjust access model as needed generateClass(file('code.template'), access, 'DB', packageName, basedir) } }
@devisnik #AndroidBuild Sqlite Access code.template package $packageName; public final class
$className { public static final class Tables { <% access.tables.each { dataSet -> %> public static final String $dataSet.name = "$dataSet. sqlName"; <% } %> } ... }
@devisnik #AndroidBuild Groovy on Android buildscript { repositories { jcenter()
} dependencies { classpath 'com.android.tools.build:gradle:1.1.0' classpath 'org.codehaus.groovy:gradle-groovy-android-plugin:0.3.6' } } apply plugin: 'groovyx.grooid.groovy-android' dependencies { compile 'org.codehaus.groovy:groovy:2.4.3:grooid' }
@devisnik #AndroidBuild Volker Leck devisnik +VolkerLeck devisnik Thank you!
@devisnik #AndroidBuild TDTD - Tester-Driven Talk Development Thanks to the
folks from Android Stammtisch Berlin for serving as Testers for a lot of the presented material. Upcoming book: Growing Subject-Oriented Talks, Guided by Testers
@devisnik #AndroidBuild Resources (in order of appearance) Gradle https://github.com/gradle/gradle Android
plugin for Gradle https://developer.android.com/tools/building/plugin-for-gradle.html gdub Tool https://github.com/dougborg/gdub Command Plugin https://github.com/novoda/gradle-android-command-plugin Gradle Plugin Portal http://plugins.gradle.org
@devisnik #AndroidBuild Resources (in order of appearance) apt Plugin https://bitbucket.org/hvisser/android-apt
Proguard Annotation Squadleader https://bitbucket.org/littlerobots/squadleader Proguard Snippets https://github.com/krschultz/android-proguard-snippets Gradle Udacity Course https://www.udacity.com/course/gradle-for-android-and-java--ud867
@devisnik #AndroidBuild Resources (in order of appearance) Versions Plugin https://github.com/ben-manes/gradle-versions-plugin
Code Analysis Plugin https://github.com/dlabs/soter Groovy library for git https://github.com/ajoberstar/grgit SDK Manager Plugin https://github.com/JakeWharton/sdk-manager-plugin
@devisnik #AndroidBuild Resources (in order of appearance) Shrink Guava Script
Snippet https://gist.github.com/devisnik/e54ea0a629adc82bcfa0 DexCount https://github.com/KeepSafe/dexcount-gradle-plugin Sqlite Analyzer Plugin https://github.com/novoda/sqlite-analyzer Groovy Android Plugin https://github.com/groovy/groovy-android-gradle-plugin
@devisnik #AndroidBuild Images http://commons.wikimedia.org/wiki/File:Perspective-Button-Stop-icon.png http://commons.wikimedia.org/wiki/File:Up-1.svg http://commons.wikimedia.org/wiki/File:Emblem-money.svg http://commons.wikimedia.org/wiki/File:Hipsterale.jpg https://commons.wikimedia.org/wiki/File:Seal_performing_tricks.jpg