Jorge Castillo
www.twitter.com/JorgeCastilloPr
www.github.com/JorgeCastilloPrz
jorge.castillo.prz@gmail.com
Developing Android apps with Java 8
About us
Candidates Companies
Our Android team Still hiring!
karumi.com
Android N Preview recently published
Java 8 appeared in the spotlight
Two new tools added to The SDK
● Jack compiler (Java Android Compiler Kit)
● Jill (Jack Intermediate Library Linker)
● Compiles Java sources directly into DEX bytecode
● Improves build times (pre-dexing, incremental compilation)
● Handles shrinking, obfuscation, repackaging and multidex
● Executes annotation processors
Jack
dependencies {
compile 'com.google.dagger:dagger:2.5'
compile 'com.jakewharton:butterknife:8.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.1.0'
annotationProcessor 'com.google.dagger:dagger-compiler:2.5'
}
Jack
Java
source files
Dex files
Shrinking
Repackaging
Obfuscation
Multidex
Jack
What about libraries? (.jar, .aar, .apklib)
Jill
Jayce
Jack
Extract Res
● Translate library dependencies to Jack format (.jack)
● Prepares them to be quickly merged with other .jack files
Select Res Resources
directory
JACK used to generate a
pre-dexed library
Jayce
Pre-dex
Res
.jack
.class
res
.jar
Jill (Jack Intermediate library linker)
APK
Predexing
● No more .class intermediate step in toolchain:
○ Bytecode manipulation tools based on .class files (like JaCoCo)
are not working anymore.
○ Lint detectors based on .class file analysis not working anymore.
● Java 8 just supported on versions >= N (API 24)*
Limitations
Okay but, how do I use the new tools ?
Let’s calm down (vamo a calmarno.)
● For new projects: File -> New project -> pick Android N
● For already started projects: Add this to your root build.gradle:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0-alpha4'
}
}
android {
compileSdkVersion 24
buildToolsVersion "24.0.0"
defaultConfig {
applicationId "com.github.jorgecastillo.java8testproject"
minSdkVersion 9
targetSdkVersion 24
jackOptions {
enabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
app build.gradle
Java 8
Supported features
● Default and static interface methods
● Lambdas
● Functional Interfaces
● Method references
● Repeatable annotations
● Some new reflection methods such as
AnnotatedElement.getAnnotationsByType(Class)
● Streams
● Optionals
minSdkVersion 24 minSdkVersion 9
● Lambdas
● Functional Interfaces (not the ones out
of the box from the JDK 8)
● Method references
● Repeatable annotations
Interfaces - Default methods
public interface DiscoverMoviesPresenter extends DiscoverMovies.Callback {
default void discoverMovies(SortingOption sortingOption) {
getLoadingView().showLoading();
getDiscoverMoviesUseCase().execute(sortingOption, this);
}
@Override default void onSuccess(List<Movie> movies) {
getLoadingView().hideLoading();
getMovieListView().renderMovies(movies);
}
@Override default void onError(String message) {
getLoadingView().hideLoading();
getMovieListView().displayRenderMoviesError(message);
}
LoadingView getLoadingView();
MovieListView getMovieListView();
DiscoverMovies getDiscoverMoviesUseCase();
}
● They make Java 8 interfaces very similar to Traits or rich interfaces
from other modern languages
● They allow developers to compose class behavior based on multiple
interfaces
● Interfaces cannot store state
Interfaces - Default methods
Interfaces - Static methods
● I would use them for utility methods tied to the contract
Interfaces - Static methods
public interface TimeMachine {
void goToTime(int hour, int minute, int seconds);
void goToDate(int day, int month, int year);
Long getCurrentTime();
Date getCurrentDate();
default ZonedDateTime getZonedDateTime(String zoneString) {
return new ZonedDateTime(getCurrentTime(), getZoneId(zoneString));
}
static Long getZoneId(String zoneString) {
// ...
return 10L;
}
}
Lambdas
● Literal representation of a function
● As in other modern languages: input args -> function body
● Assignable to variables
● Being passed as method arguments and returned as return values
(High order functions)
● First class citizen
● Translated to anonymous classes for lower API versions
Lambdas
Lambda declaration
private List<Movie> validMovies(
List<Movie> movies,
Function<Movie, Boolean> isValid) {
return movies.stream().filter(isValid::apply)
.collect(Collectors.toList());
}
Function<Movie, Boolean> isValid = movie -> movie.getId() % 2 == 0;
validMovies(movies, isValid);
validMovies(movies, movie -> movie.getId() % 2 == 0); (inline)
What if multiple args needed?
Functional Interfaces
● Provide target types for lambda expressions and method references
● Java 8 gives you some of them out of the box
Functional interfaces
Interfaces - Static methods
● Custom functional interface for lambdas with 3 input arguments
@FunctionalInterface public interface Function3<A, B, C, R> {
R apply(A a, B b, C c);
}
Function3<Long, Integer, Boolean, Boolean> isEven = (l, i, b) -> l % 2 == 0;
● Use it
Function3<Long, Integer, Boolean, Boolean> isEven2 = (l, i, b) -> {
return l % 2 == 0;
};
Method references
● Compact, easy-to-read lambda expressions for methods that
already exist
● 4 different types
Method references
// static method reference
isValid(User::isYoung);
// instance method reference
isValid(user::isOld);
String[] stringArray = {"Barbara", "James", "Ipolito", "Mary", "John"};
// Instance method reference of arbitrary type
// (string1.compareToIgnoreCase(string2))
Arrays.sort(stringArray, String::compareToIgnoreCase);
// Constructor method reference
generateUsers(User::new);
Repeatable annotations
● There are some situations where you want to apply the same
annotation to a declaration or type use.
Repeatable annotations
Streams
● Very powerful concept available in many languages
● You can extract the stream from any collection
● flatMap(), reduce(), count(), distinct(), forEach(), max(), min(), sorted(comparator) ...
Streams
users.stream()
.filter(user -> user.getAvatarUrl() != null)
.map(User::getAvatarUrl)
.findFirst()
.orElse("http://anyimage.com/fallback_avatar.png");
String avatar =
List<User> users = new ArrayList<>();
● Jack & Jill
○ Jack documentation https://source.android.com/source/jack.html
○ More details http://android-developers.blogspot.com.es/2014/12/hello-world-meet-our-new-
experimental.html
○ Annotation Processing open issue https://code.google.com/p/android/issues/detail?id=204065
● Java 8 in Android N
○ Supported features with links to documentation http://developer.android.com/preview/j8-jack.html
○ Functional Interfaces out of the box https://docs.oracle.
com/javase/8/docs/api/java/util/function/package-summary.html
Bibliography
?

Developing android apps with java 8

  • 1.
  • 2.
  • 3.
  • 4.
    Our Android teamStill hiring! karumi.com
  • 5.
    Android N Previewrecently published
  • 6.
    Java 8 appearedin the spotlight
  • 7.
    Two new toolsadded to The SDK ● Jack compiler (Java Android Compiler Kit) ● Jill (Jack Intermediate Library Linker)
  • 8.
    ● Compiles Javasources directly into DEX bytecode ● Improves build times (pre-dexing, incremental compilation) ● Handles shrinking, obfuscation, repackaging and multidex ● Executes annotation processors Jack dependencies { compile 'com.google.dagger:dagger:2.5' compile 'com.jakewharton:butterknife:8.1.0' annotationProcessor 'com.jakewharton:butterknife-compiler:8.1.0' annotationProcessor 'com.google.dagger:dagger-compiler:2.5' }
  • 9.
  • 10.
    What about libraries?(.jar, .aar, .apklib)
  • 11.
    Jill Jayce Jack Extract Res ● Translatelibrary dependencies to Jack format (.jack) ● Prepares them to be quickly merged with other .jack files Select Res Resources directory JACK used to generate a pre-dexed library Jayce Pre-dex Res .jack .class res .jar Jill (Jack Intermediate library linker)
  • 12.
  • 13.
    ● No more.class intermediate step in toolchain: ○ Bytecode manipulation tools based on .class files (like JaCoCo) are not working anymore. ○ Lint detectors based on .class file analysis not working anymore. ● Java 8 just supported on versions >= N (API 24)* Limitations
  • 14.
    Okay but, howdo I use the new tools ? Let’s calm down (vamo a calmarno.)
  • 15.
    ● For newprojects: File -> New project -> pick Android N ● For already started projects: Add this to your root build.gradle: buildscript { repositories { jcenter() } dependencies { classpath 'com.android.tools.build:gradle:2.2.0-alpha4' } }
  • 16.
    android { compileSdkVersion 24 buildToolsVersion"24.0.0" defaultConfig { applicationId "com.github.jorgecastillo.java8testproject" minSdkVersion 9 targetSdkVersion 24 jackOptions { enabled true } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } app build.gradle
  • 17.
  • 18.
  • 19.
    ● Default andstatic interface methods ● Lambdas ● Functional Interfaces ● Method references ● Repeatable annotations ● Some new reflection methods such as AnnotatedElement.getAnnotationsByType(Class) ● Streams ● Optionals minSdkVersion 24 minSdkVersion 9 ● Lambdas ● Functional Interfaces (not the ones out of the box from the JDK 8) ● Method references ● Repeatable annotations
  • 20.
  • 21.
    public interface DiscoverMoviesPresenterextends DiscoverMovies.Callback { default void discoverMovies(SortingOption sortingOption) { getLoadingView().showLoading(); getDiscoverMoviesUseCase().execute(sortingOption, this); } @Override default void onSuccess(List<Movie> movies) { getLoadingView().hideLoading(); getMovieListView().renderMovies(movies); } @Override default void onError(String message) { getLoadingView().hideLoading(); getMovieListView().displayRenderMoviesError(message); } LoadingView getLoadingView(); MovieListView getMovieListView(); DiscoverMovies getDiscoverMoviesUseCase(); }
  • 22.
    ● They makeJava 8 interfaces very similar to Traits or rich interfaces from other modern languages ● They allow developers to compose class behavior based on multiple interfaces ● Interfaces cannot store state Interfaces - Default methods
  • 23.
  • 24.
    ● I woulduse them for utility methods tied to the contract Interfaces - Static methods
  • 25.
    public interface TimeMachine{ void goToTime(int hour, int minute, int seconds); void goToDate(int day, int month, int year); Long getCurrentTime(); Date getCurrentDate(); default ZonedDateTime getZonedDateTime(String zoneString) { return new ZonedDateTime(getCurrentTime(), getZoneId(zoneString)); } static Long getZoneId(String zoneString) { // ... return 10L; } }
  • 26.
  • 27.
    ● Literal representationof a function ● As in other modern languages: input args -> function body ● Assignable to variables ● Being passed as method arguments and returned as return values (High order functions) ● First class citizen ● Translated to anonymous classes for lower API versions Lambdas
  • 28.
    Lambda declaration private List<Movie>validMovies( List<Movie> movies, Function<Movie, Boolean> isValid) { return movies.stream().filter(isValid::apply) .collect(Collectors.toList()); } Function<Movie, Boolean> isValid = movie -> movie.getId() % 2 == 0; validMovies(movies, isValid); validMovies(movies, movie -> movie.getId() % 2 == 0); (inline)
  • 29.
    What if multipleargs needed?
  • 30.
  • 31.
    ● Provide targettypes for lambda expressions and method references ● Java 8 gives you some of them out of the box Functional interfaces
  • 32.
  • 33.
    ● Custom functionalinterface for lambdas with 3 input arguments @FunctionalInterface public interface Function3<A, B, C, R> { R apply(A a, B b, C c); } Function3<Long, Integer, Boolean, Boolean> isEven = (l, i, b) -> l % 2 == 0; ● Use it Function3<Long, Integer, Boolean, Boolean> isEven2 = (l, i, b) -> { return l % 2 == 0; };
  • 34.
  • 35.
    ● Compact, easy-to-readlambda expressions for methods that already exist ● 4 different types Method references
  • 36.
    // static methodreference isValid(User::isYoung); // instance method reference isValid(user::isOld); String[] stringArray = {"Barbara", "James", "Ipolito", "Mary", "John"}; // Instance method reference of arbitrary type // (string1.compareToIgnoreCase(string2)) Arrays.sort(stringArray, String::compareToIgnoreCase); // Constructor method reference generateUsers(User::new);
  • 37.
  • 38.
    ● There aresome situations where you want to apply the same annotation to a declaration or type use. Repeatable annotations
  • 39.
  • 40.
    ● Very powerfulconcept available in many languages ● You can extract the stream from any collection ● flatMap(), reduce(), count(), distinct(), forEach(), max(), min(), sorted(comparator) ... Streams users.stream() .filter(user -> user.getAvatarUrl() != null) .map(User::getAvatarUrl) .findFirst() .orElse("http://anyimage.com/fallback_avatar.png"); String avatar = List<User> users = new ArrayList<>();
  • 41.
    ● Jack &Jill ○ Jack documentation https://source.android.com/source/jack.html ○ More details http://android-developers.blogspot.com.es/2014/12/hello-world-meet-our-new- experimental.html ○ Annotation Processing open issue https://code.google.com/p/android/issues/detail?id=204065 ● Java 8 in Android N ○ Supported features with links to documentation http://developer.android.com/preview/j8-jack.html ○ Functional Interfaces out of the box https://docs.oracle. com/javase/8/docs/api/java/util/function/package-summary.html Bibliography
  • 42.