Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)

13,769 views

Published on

As your app code gets larger and more complex, it makes sense to break your project out into smaller reusable components. But what’s the best way to do this? How can you clearly version your internal libraries? What kind of setup and maintenance can you expect? How much could it slow down development time?

In this talk we’ll dive into the various ways you can manage internal library dependencies. We’ll chat about the current state of Android dependency management, Gradle multi-project builds, Git submodules, and creating a private maven repository in Artifactory. The speaker will share real-world examples, and the pros and cons of each approach.

Published in: Software
  • Nice presentation. FYI there yet another solution to complement the git submodule and it's called git subrepo, it solves the problem of updating the external repository in a single commit without manually playing with the head. Check it out: https://github.com/ingydotnet/git-subrepo
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Internal Android Library Management (DroidCon SF 2016, Droidcon Italy 2016)

  1. 1. Internal Library Dependency Management @KellyShuster
  2. 2. @KellyShuster
  3. 3. @KellyShuster
  4. 4. dependency-sample dependency-sample-lib
  5. 5. Git Submodules Google’s Repo Tool Artifactory Jitpack
  6. 6. Git Submodules
  7. 7. dependency-sample dependency-sample-lib app mylibrary
  8. 8. 02-git-submodules
  9. 9. How do you set it up?
  10. 10. git submodule add <lib-repo>
  11. 11. 123789d a2b789d 345a89d 678789d dependency-sample dependency-sample-lib
  12. 12. 78c7046 123789d a2b789d 345a89d 678789d dependency-sample dependency-sample-lib
  13. 13. dependency-sample | +--.gitmodules +--dependency-sample-library
  14. 14. [submodule "dependency-sample-library"] path = dependency-sample-library url = https://github.com/KioKrofovitch/dependency-sample-library.git .gitmodules
  15. 15. Add Gradle References
  16. 16. settings.gradle include ':app' include ':dependency-sample-library:mylibrary'
  17. 17. build.gradle (app) dependencies { ... compile project(':dependency-sample-library:mylibrary') }
  18. 18. Check Submodule Status
  19. 19. git submodule
  20. 20. How do you get code?
  21. 21. git clone <repo> --recursive
  22. 22. git clone <repo> git submodule init git submodule update
  23. 23. git checkout <branch> git submodule init git submodule update
  24. 24. git checkout <branch>
  25. 25. git submodule init
  26. 26. git submodule update
  27. 27. Upstream changes
  28. 28. git pull git submodule update
  29. 29. Changing the library
  30. 30. ff07597 123789d a2b789d 345a89d 678789d dependency-sample dependency-sample-lib
  31. 31. 123789d a2b789d 345a89d 678789d dependency-sample dependency-sample-lib ff07597 123ff09 fef9878 345f67e
  32. 32. Committing on a Detached Head
  33. 33. How it happens
  34. 34. 1bd7125 123789d a2b789d 345a89d 678789d dependency-sample dependency-sample-lib
  35. 35. 1bd7125 123789d a2b789d 345a89d 678789d dependency-sample dependency-sample-lib 177458f
  36. 36. 1bd7125 123789d a2b789d 345a89d 678789d dependency-sample dependency-sample-lib 177458f 498defd 145458e
  37. 37. 1bd7125 177458f 498defd 145458e
  38. 38. How to recover
  39. 39. Removing Submodules
  40. 40. .gitmodules .git/modules
  41. 41. Pros Versioning brought to you by git
  42. 42. Pros Versioning brought to you by git Versioning is specific and repeatable
  43. 43. Pros Versioning brought to you by git Versioning is specific and repeatable One Android Studio Project
  44. 44. Pros Versioning brought to you by git Versioning is specific and repeatable One Android Studio Project Code access
  45. 45. Cons Magic is involved:
  46. 46. Cons Magic is involved: Working with a detached head
  47. 47. Cons Magic is involved: Working with a detached head Pulling down latest submodule
  48. 48. Cons Magic is involved: Working with a detached head Pulling down latest submodule Adding & tracking submodule reference
  49. 49. Cons Magic is involved: Working with a detached head Pulling down latest submodule Adding & tracking submodule reference Library versions are commit SHAs
  50. 50. Google’s Repo Tool
  51. 51. dependency-sample dependency-sample-lib app mylibrary dependency-parent manifest
  52. 52. 04-repo-tool
  53. 53. How do you set it up?
  54. 54. dependency-parent manifest
  55. 55. default.xml <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote ... /> <default ... /> <project ... /> </manifest>
  56. 56. default.xml <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote name="github" fetch="https://github.com" /> <default ... /> <project ... /> <project ... /> </manifest>
  57. 57. default.xml <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote ... /> <default revision="master" remote="github" /> <project ... /> </manifest>
  58. 58. default.xml <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote ... /> <default ... /> <project name="KioKrofovitch/dependency-sample" </manifest>
  59. 59. default.xml <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote ... /> <default ... /> <project name="KioKrofovitch/dependency-sample" remote="github" </manifest>
  60. 60. default.xml <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote ... /> <default ... /> <project name="KioKrofovitch/dependency-sample" remote="github" revision="04-repo-tool" </manifest>
  61. 61. default.xml <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote ... /> <default ... /> <project name="KioKrofovitch/dependency-sample" remote="github" revision="04-repo-tool" path="dependency-sample"/> </manifest>
  62. 62. default.xml <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote ... /> <default ... /> <project name="KioKrofovitch/dependency-sample" remote="github" revision="04-repo-tool" path="dependency-sample"/> <project name="KioKrofovitch/dependency-sample-library" remote="github" path="dependency-sample-library"/> </manifest>
  63. 63. default.xml <?xml version="1.0" encoding="UTF-8"?> <manifest> <remote ... /> <default ... /> <project name="KioKrofovitch/dependency-sample" remote="github" revision="04-repo-tool" path="dependency-sample"/> <project name="KioKrofovitch/dependency-sample-library" remote="github" path="dependency-sample-library"/> </manifest>
  64. 64. repo init -u <parent-repo>
  65. 65. parent | +--.repo
  66. 66. repo sync
  67. 67. parent | +--.repo +--dependency-sample +--dependency-sample-library
  68. 68. Add Gradle References
  69. 69. settings.gradle include ':app' include ':mylibrary'
  70. 70. settings.gradle include ':app' include ':mylibrary' project(':mylibrary').projectDir = new File('../dependency-sample-library/mylibrary')
  71. 71. build.gradle dependencies { ... compile project(':mylibrary') }
  72. 72. 78c7046 dependency-sample dependency-sample-lib 123789d
  73. 73. Pros Versioning is a “flexible” version of git
  74. 74. Pros Versioning is a “flexible” version of git Versions are clearly defined in one place
  75. 75. Pros Versioning is a “flexible” version of git Versions are clearly defined in one place One Android Studio project
  76. 76. Pros Versioning is a “flexible” version of git Versions are clearly defined in one place One Android Studio project Code access
  77. 77. Pros Versioning is a “flexible” version of git Versions are clearly defined in one place One Android Studio project Code access It’s cool because AOSP uses it
  78. 78. Cons Overkill?
  79. 79. Cons Overkill? Repo + Git
  80. 80. Cons Overkill? Repo + Git Detached head++
  81. 81. Cons Overkill? Repo + Git Detached head++ Documentation / Community
  82. 82. Cons Overkill? Repo + Git Detached head++ Documentation / Community Less repeatable builds
  83. 83. Multiple Repositories, Linked Using Maven
  84. 84. Artifactory
  85. 85. dependency-sample dependency-sample-lib app Artifactory mylibrary
  86. 86. dependency-sample dependency-sample-lib app mylibrary Artifactory Reference
  87. 87. dependency-sample dependency-sample-lib app Artifactory Publish mylibrary
  88. 88. 03-artifactory
  89. 89. Publishing
  90. 90. build.gradle (project level) buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.3.0' classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1" // NOTE: Do not place your application dependencies here; they // belong in the individual module build.gradle files } }
  91. 91. build.gradle (project level) buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:1.3.0' classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.1.1" // NOTE: Do not place your application dependencies here; they // belong in the individual module build.gradle files } }
  92. 92. build.gradle (mylibrary) apply plugin: 'com.android.library' apply plugin: 'com.jfrog.artifactory' apply plugin: 'maven-publish' def packageName = 'com.kiodev.myArtLibrary' def versionMajor = '1' def versionMinor = '0' def versionPatch = '0' def libraryVersion = "${versionMajor}.${versionMinor}.${versionPatch}" android { … } dependencies { … } publishing { … } artifactory { … }
  93. 93. build.gradle (mylibrary) apply plugin: 'com.android.library' apply plugin: 'com.jfrog.artifactory' apply plugin: 'maven-publish' def packageName = 'com.kiodev.myArtLibrary' def versionMajor = '1' def versionMinor = '0' def versionPatch = '0' def libraryVersion = "${versionMajor}.${versionMinor}.${versionPatch}" android { … } dependencies { … } publishing { … } artifactory { … }
  94. 94. build.gradle (mylibrary) apply plugin: 'com.android.library' apply plugin: 'com.jfrog.artifactory' apply plugin: 'maven-publish' def packageName = 'com.kiodev.myArtLibrary' def versionMajor = '1' def versionMinor = '0' def versionPatch = '0' def libraryVersion = "${versionMajor}.${versionMinor}.${versionPatch}" android { … } dependencies { … } publishing { … } artifactory { … }
  95. 95. build.gradle (mylibrary) apply plugin: 'com.android.library' apply plugin: 'com.jfrog.artifactory' apply plugin: 'maven-publish' def packageName = 'com.kiodev.myArtLibrary' def versionMajor = '1' def versionMinor = '0' def versionPatch = '0' def libraryVersion = "${versionMajor}.${versionMinor}.${versionPatch}" android { … } dependencies { … } publishing { … } artifactory { … }
  96. 96. build.gradle (mylibrary) publishing { publications { aar(MavenPublication) { groupId packageName version = libraryVersion artifactId project.getName() // Tell maven to prepare the generated "*.aar" file for publishing artifact("$buildDir/outputs/aar/${project.getName()}-release.aar") } } }
  97. 97. build.gradle (mylibrary) artifactory { contextUrl = 'http://localhost:8081/artifactory' publish { repository { ... } defaults { ... } } }
  98. 98. build.gradle (mylibrary) artifactory { contextUrl = 'http://localhost:8081/artifactory' publish { repository { // The Artifactory repository key to publish to repoKey = 'libs-release-local' // Defined in gradle.properties username = artifactory_user password = artifactory_password } defaults { … } } }
  99. 99. build.gradle (mylibrary) artifactory { contextUrl = 'http://localhost:8081/artifactory' publish { repository { ... } defaults { // Tell the Artifactory Plugin which artifacts to publish publications('aar') publishArtifacts = true // Properties to be attached to the published artifacts. properties = ['qa.level': 'basic', 'dev.team': 'core'] // Publish generated POM files to Artifactory (true by default) publishPom = true } } }
  100. 100. gradle assemble artifactoryPublish
  101. 101. Referencing
  102. 102. build.gradle (project level) allprojects { repositories { jcenter() maven { url "http://localhost:8081/artifactory/libs-release-local" // Defined in gradle.properties credentials { username = artifactory_user password = artifactory_password } } } }
  103. 103. build.gradle (app) android { … } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:design:23.0.1' compile(group: 'com.kiodev.myArtLibrary', name: 'mylibrary', version: '1.0.0', ext: 'aar') }
  104. 104. build.gradle (app) android { … } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:design:23.0.1' compile(group: 'com.kiodev.myArtLibrary', name: 'mylibrary', version: '1.0.0', ext: 'aar') }
  105. 105. gradle build --refresh-dependencies
  106. 106. Github Code changes & commits
  107. 107. Github Github Code changes & commits Pull request & merge
  108. 108. Github Github Artifactory Code changes & commits Pull request & merge Publish
  109. 109. Github Artifactory Code changes Publish
  110. 110. Pros Versioning is human readable / determined
  111. 111. Pros Versioning is human readable / determined Benefits of JAR / AAR
  112. 112. Pros Versioning is human readable / determined Benefits of JAR / AAR Potential to be highly automated
  113. 113. Cons Versioning has zero tie to git
  114. 114. Cons Versioning has zero tie to git Low security
  115. 115. Cons Versioning has zero tie to git Low security 2 Android Studio Projects
  116. 116. Cons Versioning has zero tie to git Low security 2 Android Studio Projects Stepping through code is harder
  117. 117. Cons Versioning has zero tie to git Low security 2 Android Studio Projects Stepping through code is harder Extra step of publishing
  118. 118. Jitpack
  119. 119. dependency-sample dependency-sample-lib app Jitpack mylibrary
  120. 120. 05-jitpack
  121. 121. build.gradle (project level) allprojects { repositories { jcenter() maven { url "https://jitpack.io" credentials { username authToken } } } }
  122. 122. build.gradle (project level) allprojects { repositories { jcenter() maven { url "https://jitpack.io" credentials { username authToken } } } }
  123. 123. build.gradle (app level) dependencies { ... compile 'com.github.User:repo:version' }
  124. 124. build.gradle (app level) dependencies { compile 'com.github.KioKrofovitch: dependency-sample-library: 02-git-submodules-SNAPSHOT' }
  125. 125. <tag> -SNAPSHOT <branch>-SNAPSHOT <short commit SHA>
  126. 126. gradle build --refresh-dependencies
  127. 127. Pros Versioning: Human readable AND managed by Git
  128. 128. Pros Versioning: Human readable AND managed by Git Benefits of JAR / AAR
  129. 129. Pros Versioning: Human readable AND managed by Git Benefits of JAR / AAR No publishing stress
  130. 130. Cons Waiting for publishing
  131. 131. Cons Waiting for publishing Potential for non-repeatable builds
  132. 132. Cons Waiting for publishing Potential for non-repeatable builds 2 Android Studio Projects
  133. 133. Cons Waiting for publishing Potential for non-repeatable builds 2 Android Studio Projects Stepping through code is harder
  134. 134. Git Submodules Google’s Repo Tool Artifactory Jitpack
  135. 135. @KellyShuster https://github.com/KioKrofovitch/ dependency-sample dependency-sample-library dependency-parent
  136. 136. Resources Git submodule https://git-scm.com/docs/git-submodule https://git-scm.com/book/en/v2/Git-Tools-Submodules Repo Tool http://www.instructables.com/id/Using-Googles-repo-command-in-your-own-projects/ Artifactory Open Source https://www.jfrog.com/open-source/ Artifactory Professional https://www.jfrog.com/artifactory/ Artifactory OS Tutorial https://jeroenmols.github.io/blog/2015/08/06/artifactory/
  137. 137. Photo Credits Android Robot https://commons.wikimedia.org/wiki/File:Android_robot.svg Trinity College Library https://en.wikipedia.org/wiki/Trinity_College,_Dublin#/media/File:Long_Room_Interior, _Trinity_College_Dublin,_Ireland_-_Diliff.jpg Ruby http://nicholasjohnson.com/ruby/ Clean Desk http://www.levo.com/articles/career-advice/what-your-desk-says-about-you Messy Desk http://www.telegraph.co.uk/news/newstopics/howaboutthat/10225664/Having-a-messy-desk-makes-you-more- creative.html Headless Horseman Gif https://www.lovethisgif.com/tag/headless+horseman Ghost http://38.media.tumblr.com/d30fe069cc48e11eeb31ae08293a159e/tumblr_nbtdxg9d6n1szf0nzo1_250.gif
  138. 138. Photo Credits Neverending Story Book http://www.dailyrecord.co.uk/entertainment/tv-radio/flashback-friday-neverending-story-proves-4948514 Unicorn w/ Rainbows http://souloftruth.com/the-race-to-nowhere/ John Wayne http://patch.com/california/sanclemente/best-ways-recycle-water-during-californias-dry-spell Space Pic http://wallpapershidef.com/outer-space-desktop-wallpaper.html Computer https://commons.wikimedia.org/wiki/File:Gnome-computer.svg Crying Pikachu http://gifrific.com/wp-content/uploads/2012/06/Picachu-crying-pokemon.gif Branch http://townhack.github.io/git-101/img/git-branch.png
  139. 139. Photo Credits Maven Logo https://commons.wikimedia.org/wiki/File:Maven_logo.svg

×