Top Banner
Retrolambda Use Lambdas in Android kojilin@Cubie Inc. 2015/1/28
35

Use Lambdas in Android

Jul 14, 2015

Download

Software

Koji Lin
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Use Lambdas in Android

Retrolambda Use Lambdas in Android

kojilin@Cubie Inc.2015/1/28

Page 2: Use Lambdas in Android

Lambda?

Page 3: Use Lambdas in Android

input.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { }});

Page 4: Use Lambdas in Android

input.setOnClickListener(v -> { ...});

Page 5: Use Lambdas in Android

Lambda Syntax

(int x, int y) -> x + y

Page 6: Use Lambdas in Android

(int x, int y) -> x + yArgument List

Page 7: Use Lambdas in Android

(int x, int y) -> x + yArrow Token

Page 8: Use Lambdas in Android

(int x, int y) -> x + yBody

Page 9: Use Lambdas in Android

(int x, int y) -> x + y

() -> 42

(String s) -> { System.out.println(s); }

● Body is expression

● Body is statement block

Page 10: Use Lambdas in Android

input.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { }});

Page 11: Use Lambdas in Android

input.setOnClickListener(v -> { ...});

Page 12: Use Lambdas in Android

input.setOnClickListener(v -> ...);

Page 13: Use Lambdas in Android

為何開心?• 各種用到 anonymous class 的狀況

• Event listener• Runnable• RxJava• Future / Promise Pattern API

Page 14: Use Lambdas in Android

input.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { }});

Page 15: Use Lambdas in Android

input.setOnClickListener(v -> { ...});

Page 16: Use Lambdas in Android

handler.post(new Runnable() { @Override public void run() { ... }});

Page 17: Use Lambdas in Android

handler.post(() -> { ...});

Page 18: Use Lambdas in Android

Observable.from(new Integer[] {...}) .filter(new Func1<Integer, Boolean>() { @Override public Boolean call(Integer v) { return v < 4; }}).subscribe(new Action1<Integer>() { @Override public void call(Integer value) { System.out.println("Value: " + value); }});

Page 19: Use Lambdas in Android

Observable.from(new Integer[] {...}) .filter(v -> v < 4) .subscribe(value -> { System.out.println("Value: " + value); });

Page 20: Use Lambdas in Android

設定只要幾個步驟

Page 21: Use Lambdas in Android

下載 JDK 8

Page 22: Use Lambdas in Android

build.gradle

buildscript { ... dependencies { classpath 'me.tatarka:gradle-retrolambda:2.5.0' }}...apply plugin: 'me.tatarka.retrolambda'...

Page 23: Use Lambdas in Android

設定原始碼支援Java 8 語法

Page 24: Use Lambdas in Android

• ProGuard

• -dontwarn java.lang.invoke.**

• 而且 IDE Debug feature 也沒問題

Page 25: Use Lambdas in Android

好像很不錯,馬上導入 !?

Page 26: Use Lambdas in Android

好像很不錯,馬上導入 !?

等一下!!!

Page 27: Use Lambdas in Android

怎麼做到的?

Page 28: Use Lambdas in Android

Java source(.java)

Java bytecode(.class)

Dalvik bytecode(.dex)

Page 29: Use Lambdas in Android

Java source(.java)

Java bytecode(.class)

Dalvik bytecode(.dex)

Java 8 bytecode Java 5/6/7 bytecode

Page 30: Use Lambdas in Android

• 未來 JDK 編譯出的 bytecode 改變

• 需等 retrolambda 支援

• 不支援的話,就得持續使用舊版 JDK

• Android 新的編譯過程不經過 bytecode

• Jack & Jill

• 新增修改程式碼有時會有 NoClassDefFoundError

• 未來 Android 上的 Java 語法應該(!?)會有 Java 8,所

以程式碼切換過去也不用改變

Page 31: Use Lambdas in Android

另外...

Page 32: Use Lambdas in Android

List<Integer> list = Arrays.asList(1,2,3);Integer sum = list.stream() .map(i -> i * 2) .reduce(0, (x, y) -> x + y);

Page 33: Use Lambdas in Android

List<Integer> list = Arrays.asList(1,2,3);Integer sum = list.stream() .map(i -> i * 2) .reduce(0, (x, y) -> x + y);

等一下!!!

Page 34: Use Lambdas in Android

• 因為是支援 lambda 語法,所以 java 8 的 API 並

沒有支援

• 可以使用 Guava, FunctionalJava 類的專案

Integer sum = fj.data.List.list(1,2,3) .map(i -> i * 2) .foldLeft(i -> (j -> i + j), 0);

Page 35: Use Lambdas in Android

除了 lambda 外其他好處

• Method reference

• Effective Final

• Generalized Target-Type Inference

input.setOnClickListener(System.out::println);