reactive functional programming with java 8 on android n

22
Reactive Functional Programming with Java 8 on Android N Shipeng Xu May 6th 2016

Upload: shipeng-xu

Post on 15-Feb-2017

109 views

Category:

Technology


2 download

TRANSCRIPT

Page 1: Reactive Functional Programming with Java 8 on Android N

Reactive Functional Programming with Java 8

on Android NShipeng Xu

May 6th 2016

Page 2: Reactive Functional Programming with Java 8 on Android N

What is Reactive Programming?

Page 3: Reactive Functional Programming with Java 8 on Android N

Observer Pattern

Page 4: Reactive Functional Programming with Java 8 on Android N

An Observable emits items. A Subscriber consumes those items.

(from RxJava in practice)

Observable Subscriber

Items

Observable & Subscriber

Page 5: Reactive Functional Programming with Java 8 on Android N

Observable Transform

Items

Subscriber

Observable & Subscriber

Page 6: Reactive Functional Programming with Java 8 on Android N

Why Reactive Programming?

Page 7: Reactive Functional Programming with Java 8 on Android N

Quick example• Find all png images under a folder

• Load the images into a gallery view

Page 8: Reactive Functional Programming with Java 8 on Android N

http://gank.io/post/560e15be2dca930e00da1083

new Thread() { @Override public void run() { super.run(); for (Folder folder : folders) { File[] files = folder.listFiles(); for (File file : files) { if (file.getName().endsWith(".png")) { final Bitmap bitmap = getBitmapFromFile(file); getActivity().runOnUiThread(new Runnable() { @Override public void run() { imageCollectorView.addImage(bitmap); } }); } } } } }.start();

Vanilla Java

Page 9: Reactive Functional Programming with Java 8 on Android N

http://gank.io/post/560e15be2dca930e00da1083

Observable.from(folders) .flatMap((folder) -> Observable.from(folder.listFiles()) ) .filter((file) -> file.getName().endsWith(".png") ) .map((file) -> getBitmapFromFile(file) ) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe((bitmap) -> imageCollectorView.addImage(bitmap) );

RxJava

Page 10: Reactive Functional Programming with Java 8 on Android N

Create an Observable

Observable observable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("Hello"); subscriber.onNext("World"); subscriber.onCompleted(); } });

observable.subscribe(subscriber);To subscribe to an observable:

Observable.just("Hello", "World")

Or the shorter version:

Page 11: Reactive Functional Programming with Java 8 on Android N

Subscriber<String> subscriber = new Subscriber<String>() { @Override public void onNext(String s) { Log.d(tag, "Item: " + s); }

@Override public void onCompleted() { Log.d(tag, "Completed!"); }

@Override public void onError(Throwable e) { Log.d(tag, "Error!"); } };

Subscriber Sample

Page 12: Reactive Functional Programming with Java 8 on Android N

http://reactivex.io/documentation/observable.htmlhttp://rxmarbles.com/

Page 13: Reactive Functional Programming with Java 8 on Android N
Page 14: Reactive Functional Programming with Java 8 on Android N

Demo project

Page 15: Reactive Functional Programming with Java 8 on Android N

Get started with Java 8 on Android N

android { compileSdkVersion 'android-N' buildToolsVersion "24.0.0 rc1" defaultConfig { applicationId "me.billhsu.rxdemo" minSdkVersion 'N' targetSdkVersion 'N' versionCode 1 versionName "1.0" jackOptions { enabled true } } compileOptions { targetCompatibility 1.8 sourceCompatibility 1.8 } }

Page 16: Reactive Functional Programming with Java 8 on Android N

Rx libraries for AndroidRxAndroid - Provide a Scheduler that schedules on the main thread or any given Looper. RxLifecycle - Lifecycle handling APIs for Android apps using RxJava RxBinding - RxJava binding APIs for Android's UI widgets. SqlBrite - A lightweight wrapper around SQLiteOpenHelper and ContentResolver which introduces reactive stream semantics to queries. Android-ReactiveLocation - Library that wraps location play services API boilerplate with a reactive friendly API. rx-preferences - Reactive SharedPreferences for Android RxFit - Reactive Fitness API Library for Android RxWear - Reactive Wearable API Library for Android RxPermissions - Android runtime permissions powered by RxJava RxNotification - Easy way to register, remove and manage notifications using RxJava

Page 17: Reactive Functional Programming with Java 8 on Android N

Android Scheduler

Schedulers.io() Schedulers.computation() Schedulers.newThread() Schedulers.from(Executor) Schedulers.immediate() Schedulers.trampoline()

Observable.just("Hello", "World") .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(/* update UI*/);

Page 18: Reactive Functional Programming with Java 8 on Android N

REST Responses to Observables

public interface GitHubApi { @GET("users/{users}/followers") Observable<List<GitHubUser>> getFollowers(@Path("users") String user);

@GET("users/{users}") Observable<GitHubUser> getUser(@Path("users") String user); }

private void setupRetrofit() { OkHttpClient client = new OkHttpClient(); client.setConnectTimeout(5, TimeUnit.SECONDS); Retrofit retrofit = new Retrofit.Builder() .client(client) .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .baseUrl("https://api.github.com/") .build(); gitHubApi = retrofit.create(GitHubApi.class); }

https://api.github.com/users/billhsu

Page 19: Reactive Functional Programming with Java 8 on Android N

RxView.clicks(button).subscribe((a) -> { button.setClickable(false); adapter.getGitHubUserList().clear(); adapter.notifyDataSetChanged(); progressBar.setVisibility(View.VISIBLE); gitHubApi.getFollowers(userName.getText().toString()) .flatMapIterable(users -> users) .flatMap(user -> gitHubApi.getUser(user.getLogin())) .filter(user -> !TextUtils.isEmpty(user.getCompany())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( user -> { adapter.getGitHubUserList().add(user); adapter.notifyDataSetChanged(); }, error -> { Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show(); button.setClickable(true); progressBar.setVisibility(View.GONE); }, () -> { button.setClickable(true); progressBar.setVisibility(View.GONE); }); });

The click stream

Page 20: Reactive Functional Programming with Java 8 on Android N

Click stream to GitHubUser Stream

RxView.clicks(button).subscribe((a) -> { button.setClickable(false); adapter.getGitHubUserList().clear(); adapter.notifyDataSetChanged(); progressBar.setVisibility(View.VISIBLE); gitHubApi.getFollowers(userName.getText().toString()) .flatMapIterable(users -> users) .flatMap(user -> gitHubApi.getUser(user.getLogin())) .filter(user -> !TextUtils.isEmpty(user.getCompany())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( user -> { adapter.getGitHubUserList().add(user); adapter.notifyDataSetChanged(); }, error -> { Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show(); button.setClickable(true); progressBar.setVisibility(View.GONE); }, () -> { button.setClickable(true); progressBar.setVisibility(View.GONE); }); });

Page 21: Reactive Functional Programming with Java 8 on Android N

Subscribe to GitHubUser Stream

RxView.clicks(button).subscribe((a) -> { button.setClickable(false); adapter.getGitHubUserList().clear(); adapter.notifyDataSetChanged(); progressBar.setVisibility(View.VISIBLE); gitHubApi.getFollowers(userName.getText().toString()) .flatMapIterable(users -> users) .flatMap(user -> gitHubApi.getUser(user.getLogin())) .filter(user -> !TextUtils.isEmpty(user.getCompany())) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( user -> { adapter.getGitHubUserList().add(user); adapter.notifyDataSetChanged(); }, error -> { Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show(); button.setClickable(true); progressBar.setVisibility(View.GONE); }, () -> { button.setClickable(true); progressBar.setVisibility(View.GONE); }); });

Page 22: Reactive Functional Programming with Java 8 on Android N

Summary