Java 8 on Android

Why

Java 8 > Java 6/7

Because 8 > 7 && 8 > 6

Java 8/JDK8 provides:

  • Lambdas!
  • Local type inference
  • Default methods
  • Streams API
  • Date and Time API

Problem

Android only support

Java 6

Android support Java 7 from API 19

Solution

A few of them

Lambdas

The hardest part

Java 6

button.setOnClickListener(new View.OnClickListener() {
    @Override                                         
    public void onClick(View view) {                  
        view.setEnabled(false);                       
    }                                                 
});                                                   

Java 8

button.setOnClickListener((View view) -> {
    view.setEnabled(false);               
});                                       
button.setOnClickListener((View view) -> view.setEnabled(false));
button.setOnClickListener((view) -> view.setEnabled(false));
button.setOnClickListener(view -> view.setEnabled(false));

Sollution

We need to use compile Java8 to Java6

How does it work?

  1. Take Java 8 code
  2. Compile it with javac from JDK8
  3. Process bytecode
  4. ?????????????
  5. PROFIT

Retrolamda support

  • Lambdas
  • Serializable lambdas
  • Method references
  • Try-with-resources
  • Default Methods
  • Static method in interfaces

Easy to use with gradle

buildscript {
  repositories {
     mavenCentral()
  }

  dependencies {
     classpath 'me.tatarka:gradle-retrolambda:3.2.2'
  }
}

// Required because retrolambda is on maven central
repositories {
  mavenCentral()
}

apply plugin: 'com.android.application' //or apply plugin: 'java'
apply plugin: 'me.tatarka.retrolambda'

One more thing

//anonymous class holds outer reference                   
button.setOnClickListener(new View.OnClickListener() {    
    @Override                                             
    public void onClick(View view) {                      
        view.setEnabled(false);                           
    }                                                     
});                                                       
                                                          
                                                          
//do not hold reference to outer class                    
button.setOnClickListener(view -> view.setEnabled(false));

Avoid memory leaks

Streams API

backport of streams

Java 8/Streams

Java 6/Streamsupport

List<String> myList =                         
  Arrays.asList("a1", "a2", "b1", "c2", "c1");
                                              
myList.stream()                               
        .filter(s -> s.startsWith("c"))       
        .map(String::toUpperCase)             
        .sorted()                             
        .forEach(System.out::println);        
List<String> myList =                         
  Arrays.asList("a1", "a2", "b1", "c2", "c1");
                                              
StreamSupport.stream(myList)                  
        .filter(s -> s.startsWith("c"))       
        .map(String::toUpperCase)             
        .sorted()                             
        .forEach(System.out::println);        

Date and Time

Backport of JSR-310 API

and ThreeTenABP for Android

    // The current date and time
    LocalDateTime dateTime = LocalDateTime.now();
    // from values
    LocalDate d1 = LocalDate.of(2015, Month.SEPTEMBER, 17);

    // construct time object based on hours and minutes
    LocalTime t1 = LocalTime.of(17, 18);
    // create time object based on a String
    LocalTime t2 = LocalTime.parse("10:15:30");

    // Get the time or date from LocalDateTime
    LocalDate date = dateTime.toLocalDate();
    Month month = dateTime.getMonth();
    int day = dateTime.getDayOfMonth();
    int minute = dateTime.getMinute();
    
    
    // Perform operations on these objects will always return a new object
    // as these objects are immutable
    
    LocalDateTime updatedDate = dateTime.withDayOfMonth(13).withYear(2015);
    LocalDateTime plusYears = updatedDate.plusDays(25).plusYears(2);
    
    // the API also allow to use Adjusters for the API,
    // for example the following will set the day to the last day in the monthd
    LocalDateTime newDate = dateTime.with(TemporalAdjusters.lastDayOfMonth());
    
    // You can also truncate certain time units, e.g., remove the seconds from a time 
    // object
    LocalTime truncatedSeconds = t2.truncatedTo(ChronoUnit.SECONDS);

Questions?

Java 8 on Android

By Yaroslav Heriatovych