[113] lessons from realm
-
Upload
naver-d2 -
Category
Technology
-
view
9.805 -
download
0
Transcript of [113] lessons from realm
DEVELOPING ANDROID LIBRARIES: LESSONS FROM REALM
EMANUELE ZATTIN (@EMANUELEZ)
DEVIEW, SEPTEMBER 14, 2015
MODULARITYThe ability to split your code base into several units with well defined interface. This allows to focus on smaller problems, producing more
testable code
REUSABILITYA consequence of modularity. Now you can use that unit again in several
places in your projects or accross several different ones
SHAREABILITYA consequence or reusability. You found a nice way to solve a particular
issue. Why now helping other developers? Get your name out there!
THE PROBLEMANDROID STUDIO ALLOWS YOU TO:
▸ Create a new Application project▸ Create a new Library project▸ Add a new Application module▸ Add a new Library module
SOLUTION 1From Android Studio:
1. Create a new Application project2. Add a new Library module
3. Remove the Application module
SOLUTION 2From the command line:
android create lib-project -t 1 -k kr.deview.awesomelib -p . -g -v 1.3.0
-t: target (Use android list targets to get a list of target ids)-k: package name-p: path to the project-g: make it a Gradle project (requires SDK >= 19)-v: version of the Android Gradle plugin to use
▸ Easy to learn▸ Easy to use, even without documentation
▸ Hard to misuse▸ Easy to read and maintain code that uses it▸ Sufficiently powerful to satisfy requirements
▸ Easy to extend▸ Appropriate to audience
STAND ON THE SHOUDERS OF GIANTS▸ Effective Java 2 by Joshua Bloch
▸ How To Design A Good API and Why it Matters by Joshua Bloch
TESTING IS EVEN MORE IMPORTANT FOR LIBRARIES THAN FOR APPLICATIONS
BECAUSE YOU HAVE NO IDEA HOW YOUR CUSTOMERS ARE GOING TO USE IT.
USEFUL JENKINS PLUGINS
▸ Job Config History▸ Git
▸ Android Emulator▸ Matrix Job2
▸ Junit2
2 It comes preloaded with Jenkins
HOW TO PRODUCE A SOURCE JARtask androidSourcesJar(type: Jar) { from android.sourceSets.main.java.srcDirs}
HOW TO PRODUCE A JAVADOC JARandroid.libraryVariants.all { variant -> task("javadoc${variant.name.capitalize()}", type: Javadoc) { description "Generates Javadoc for $variant.name." group 'Docs' source = variant.javaCompile.source ext.androidJar = files(project.android.getBootClasspath()) classpath = files(variant.javaCompile.classpath.files) + ext.androidJar exclude '**/BuildConfig.java' exclude '**/R.java' }}
Bintray also provides a Gradle plugin for the actual publishing
The configuration is not trivial, and in the beginning it might be easier to just do the release manually on the binary website
Sometimes libraries need to be smart behind the scenes to save the user from writing boilerplate code
! PROS:
▸ It allows you to write new Java files▸ It happens at compilation time
! CONS▸ It does not allow to modify existing code
▸ It's not very easy to use
WORKAROUNDCreate two Java sub-projects:
1. annotations (used both by the library and the processor)2. annotations processor
YOU NEED TO INCLUDE THE ANNOTATIONS IN THE JAVADOCandroid.libraryVariants.all { variant -> task("javadoc${variant.name.capitalize()}", type: Javadoc) { description "Generates Javadoc for $variant.name." group 'Docs' source = variant.javaCompile.source source "../annotations/src/main/java" // <-- Remember this! ext.androidJar = files(project.android.getBootClasspath()) classpath = files(variant.javaCompile.classpath.files) + ext.androidJar exclude '**/BuildConfig.java' exclude '**/R.java' }}
! PROS:
▸ It allows you to write new Java files▸ It happens at compilation time
! CONS▸ It does not allow to modify existing code
▸ It's not very easy to use
! PROS:
▸ It allows to modify existing code ❤▸ It's easier to use compared to Annotation Processing
! CONS▸ You really need to know what you are doing▸ It might look weird in the debugger
HOW TO START USING ITbuildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle-experimental:0.2.0' }}
apply plugin: 'com.android.model.application'
THE DSL IS SLIGHTLY DIFFERENTmodel { // <-- This! android { compileSdkVersion = 22 // Now it's a property, not a method buildToolsVersion = "22.0.1" // Same here and the rest of the example
defaultConfig.with { // Use the with method applicationId = "com.example.user.myapplication" minSdkVersion.apiLevel = 15 // Use the apiLevel property targetSdkVersion.apiLevel = 22 // Same here versionCode = 1 versionName = "1.0" } }}