rx java x retrofit
TRANSCRIPT
2015.11.27
オープンソースライブラリ研究会 Android編Shun Nakahara
自己紹介
✤ Shun Nakahara
✤ 27
✤ iOS/Android
✤ iOS 大好きです!
✤ @shun_nakahara
全員エンジニア合コンをやってみた人生初の合コン
FiNC 紹介
一生に一度のかけがえのない人生の成功をサポートする
iOS 大好きです!!
iOS で発表したかったんですが…
RxJava + Retrofit
RxJava + Retrofit
✤ RxJava を簡単に紹介
✤ Retrofit を簡単に紹介
✤ 二つを合わせたテクニックを紹介
RxJava
RxJava
✤ Reactive Extensions Java
✤ リアクティブプログラミングをするためのライブラリ
✤ 同期処理、非同期処理、遅延実行…
RxJava
✤ 基本的な使い方
✤ 非同期処理
✤ 同期処理
✤ RxAndroid
Gradle の準備
// RxJavacompile 'io.reactivex:rxjava:1.0.15'
基本的な書き方
String name = “shun"; Subscription subscription = Observable.from(new String[]{name}).subscribe(new Action1<String>() { @Override public void call(String string) { String name = "nakahara " + string; System.out.print(name); } }); subscription.unsubscribe();
基本的な処理を便利に!?
Observable.OnSubscribe<String> onSubscribe = new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { final String name = "shun"; // 重い処理などをここで行う。 String fullName = "nakahara " + name; subscriber.onNext(fullName); subscriber.onCompleted(); } }; Subscription subscription = Observable.create(onSubscribe).subscribe(new Action1<String>() { @Override public void call(String string) { System.out.print(string); } }); subscription.unsubscribe();
非同期処理
Observable.OnSubscribe<String> onSubscribe = new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { // 通信処理 boolean isSuccess = false; String response = "response"; if (isSuccess) { subscriber.onNext(response); subscriber.onCompleted(); } else { subscriber.onError(new NetworkErrorException("connect error")); } }}; Observable<String> stringObservable = Observable.create(onSubscribe); stringObservable.subscribe(new Observer<String>() { @Override public void onCompleted() { // network completed } @Override public void onError(Throwable e) { // network error message } @Override public void onNext(String string) { // network success response } });
同期処理を書きたい時Observable.OnSubscribe<String> onSubscribe = new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { // 通信処理 boolean isSuccess = false; String response = "response"; if (isSuccess) { subscriber.onNext(response); subscriber.onCompleted(); } else { subscriber.onError(new NetworkErrorException("connect error")); } }}; Observable<String> stringObservable = Observable.create(onSubscribe); String response = stringObservable.toBlocking().single(); if (response == null) { // error} else { // success}
気づいた人いますか?
メソッドに切す
public Observable<String> request() { Observable.OnSubscribe<String> onSubscribe = new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { // 通信処理 boolean isSuccess = false; String response = "response"; if (isSuccess) { subscriber.onNext(response); subscriber.onCompleted(); } else { subscriber.onError(new NetworkErrorException("connect error")); } } }; return Observable.create(onSubscribe); }
非同期処理
request().subscribe(new Observer<String>() { @Override public void onCompleted() { // network completed } @Override public void onError(Throwable e) { // network error } @Override public void onNext(String s) { // response call back } });
同期処理
String response = request().toBlocking().single(); if (response == null) { // network error} else { // response call back}
なんだかこれだと使えそうな 気がしますね!d(‾ ‾)
RxAndroid
✤ Reactive Extensions Android
✤ リアクティブプログラミングをするためのライブラリ
✤ 同期処理、非同期処理、遅延実行…
✤ RxJavaを内包しAndroidで利用するための機能を追加
✤ Android Handler / Thread 処理
RxAndroid…他にも
✤ RxLifecycle
✤ RxBinding
✤ SqlBrite
✤ Android-ReactiveLocation
✤ rx-preferences
RxAndroid
✤ AndroidSchedulers
✤ HandlerSchedulers
Gradle の準備
// RxJavacompile 'io.reactivex:rxjava:1.0.15'// RXAndroidcompile 'io.reactivex:rxandroid:1.0.1'
Android Schedulers
request().subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<String>() { @Override public void onCompleted() { // network completed // main thread } @Override public void onError(Throwable e) { // network error // main thread } @Override public void onNext(String s) { // response call back // main thread } });
Handler Schedulers
Handler handler = new Handler(); request().subscribeOn(Schedulers.newThread()) .observeOn(HandlerScheduler.from(handler)) .subscribe(new Observer<String>() { @Override public void onCompleted() { // network completed // handler thread } @Override public void onError(Throwable e) { // network error // handler thread } @Override public void onNext(String s) { // response call back // handler thread } });
RxJava わかってきたところで
Retrofit
Retrofit
✤ A Type safe HTTP client for Android and Java
✤ Android の為の REST 通信を手軽に実装できる!?
✤ Retrofit 2.0.0-bata2 を利用します。
Retrofit
✤ 基本的な使い方
✤ 非同期処理
✤ 同期処理
✤ RxJava を組み込んでみる
Gradle の準備
// Retrofitcompile ‘com.squareup.retrofit:retrofit:2.0.0-beta2'
// gsoncompile ‘com.google.code.gson:gson:2.4'
// Converter Gsoncompile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
Proguard の準備
# Retrofit Proguard-dontwarn retrofit.**-keep class retrofit.** { *; } -keepattributes Signature-keepattributes Exceptions
基本的な使い方
Model Class の作成
public class SignIn { @SerializedName("access_token") public final String accessToken; @SerializedName("user_id") public final int userId; @SerializedName("group_id") public final int group_id; public SignIn(String accessToken, int userId, int group_id) { this.accessToken = accessToken; this.userId = userId; this.group_id = group_id; } }
Service Interface 作成
public interface UsersService { @FormUrlEncoded @POST("/v3/users/sign_in") Call<SignIn> signIn(@Field("email") String email, @Field("password") String password); }
Service Interface 作成
public interface UsersService { @FormUrlEncoded @POST("/v3/users/sign_in") Call<SignIn> signIn(@Field("email") String email, @Field("password") String password); }
非同期処理
// Gson Converter FactoryGsonConverterFactory factory = GsonConverterFactory.create(new Gson()); // RetrofitRetrofit retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(factory) .build(); // Users ServiceUsersService usersService = retrofit.create(UsersService.class); // CallCall<SignIn> call = usersService.signIn(Email, Password); call.enqueue(new Callback<SignIn>() { @Override public void onResponse(Response<SignIn> response, Retrofit retrofit) { // network success } @Override public void onFailure(Throwable t) { // network error } });
同期処理
// Gson Converter FactoryGsonConverterFactory factory = GsonConverterFactory.create(new Gson()); // RetrofitRetrofit retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(factory) .build(); // Users ServiceUsersService usersService = retrofit.create(UsersService.class); // CallCall<SignIn> call = usersService.signIn(Email, Password); try { Response<SignIn> response = call.execute(); } catch (IOException e) { e.printStackTrace(); }
・・・
クラッシュ
RxJava + Retrofit
Service Interface(RxJava版)
public interface UsersService { @FormUrlEncoded @POST("/v3/users/sign_in") Observable<SignIn> signIn(@Field("email") String email, @Field("password") String password); }
非同期処理(RxJava版)
// Gson Converter FactoryGsonConverterFactory factory = GsonConverterFactory.create(new Gson()); // RxJava Call AdapterRxJavaCallAdapterFactory adapterFactory = RxJavaCallAdapterFactory.create();// RetrofitRetrofit retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(factory) .addCallAdapterFactory(adapterFactory) .build(); // Users ServiceUsersService usersService = retrofit.create(UsersService.class); // User ServiceObservable<SignIn> observable = usersService.signIn(Email, Password); observable.subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<SignIn>() { @Override public void onCompleted() { // network completed } @Override public void onError(Throwable e) { // network error } @Override public void onNext(SignIn signIn) { // network success } });
同期処理(RxJava版)
// Gson Converter FactoryGsonConverterFactory factory = GsonConverterFactory.create(new Gson()); // RxJava Call AdapterRxJavaCallAdapterFactory adapterFactory = RxJavaCallAdapterFactory.create(); // RetrofitRetrofit retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .addConverterFactory(factory) .addCallAdapterFactory(adapterFactory) .build(); // Users ServiceUsersService usersService = retrofit.create(UsersService.class); // CallObservable<SignIn> observable = usersService.signIn(Email, Password); SignIn signIn = observable .subscribeOn(Schedulers.newThread()) .toBlocking() .single(); if (signIn == null) { // network error} else { // network success}
Retrofit でハマったこと
Retrofit でハマったこと
✤ Twitter Kit では Retrofit 1.8 を使っている
✤ Retrofit 1.8-1.9 と Retrofit 2.0 で設定の変更
✤ Retrofit 2.0 では、RxJava の Call Adapter が必要
ありがとうございました。