use lambdas in android

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

Upload: koji-lin

Post on 14-Jul-2015

540 views

Category:

Software


0 download

TRANSCRIPT

Retrolambda Use Lambdas in Android

kojilin@Cubie Inc.2015/1/28

Lambda?

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

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

Lambda Syntax

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

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

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

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

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

() -> 42

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

● Body is expression

● Body is statement block

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

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

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

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

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

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

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

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

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

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); }});

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

設定只要幾個步驟

下載 JDK 8

build.gradle

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

設定原始碼支援Java 8 語法

• ProGuard

• -dontwarn java.lang.invoke.**

• 而且 IDE Debug feature 也沒問題

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

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

等一下!!!

怎麼做到的?

Java source(.java)

Java bytecode(.class)

Dalvik bytecode(.dex)

Java source(.java)

Java bytecode(.class)

Dalvik bytecode(.dex)

Java 8 bytecode Java 5/6/7 bytecode

• 未來 JDK 編譯出的 bytecode 改變

• 需等 retrolambda 支援

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

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

• Jack & Jill

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

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

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

另外...

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

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

等一下!!!

• 因為是支援 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);

除了 lambda 外其他好處

• Method reference

• Effective Final

• Generalized Target-Type Inference

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