Reactive Functional Programming with Java 8 on Android N
- 4. An Observable emits items.
A Subscriber consumes those items.
(from RxJava in practice)
Observable Subscriber
Items
Observable & Subscriber
- 8. 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
- 10. 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:
- 11. 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
- 15. 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
}
}
- 16. Rx libraries for Android
RxAndroid - 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
- 18. 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
- 20. 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);
});
});
- 21. 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);
});
});