Retrofit+Rx
RetrofitのRx化に関しては Jake神作のAdapterを使っていたらしい。。が
現在本家のretrofitにAdapterが出来てるみたいで Jake神作のは
現在本家のretrofitにAdapterが出来てるみたいで Jake神作のは
DEPRECATED
になっている。
こちらを使う
環境構築
app/build.gradle
に以下を追加 implementation 'io.reactivex.rxjava2:rxjava:2.1.6'
implementation 'io.reactivex.rxjava2:rxkotlin:2.1.0'
implementation 'com.squareup.moshi:moshi:1.5.0'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.4.0'
実装
簡単なサンプル
サンプルとしても多い、GithubのAPIを使ってユーザー情報を取得して見ます。
- Userクラス (ユーザー情報を格納するデータクラス)
import com.squareup.moshi.Json data class User( @Json(name = "name") var name: String, @Json(name = "login") var login: String, @Json(name = "blog") var blog: String, @Json(name = "type") var type: String )
- GithubApiクラス (interfaceを定義)
import io.reactivex.Observable import retrofit2.http.GET import retrofit2.http.Path interface GithubApi { companion object { const val BASE_URL = "https://api.github.com" } @GET("users/{username}") fun getUser(@Path("username") user: String): Observable<User> }
- MainActivityクラス
class MainActivity : AppCompatActivity() { companion object { val TAG = MainActivity::class.java.simpleName } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val retrofit = Retrofit.Builder() .baseUrl(GithubApi.BASE_URL) .addConverterFactory(MoshiConverterFactory.create(Moshi.Builder().build())) .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io())) .build() val service = retrofit.create(GithubApi::class.java) service.getUser("Slowhand0309").subscribe({ ret -> Log.d(TAG, "ret $ret") }, { error -> Log.e(TAG, error.message) }) } }
AndroidManifestに
<uses-permission android:name="android.permission.INTERNET"/>
を追加するのを忘れずに戻り値に関して
RetrofitのRxJava2 Adapterは戻り値として
Observable, Single, Maybe, Completable
を提供しているが、それぞれの違いがわからないので調べてみる。
Observable, Single, Maybe, Completable
を提供しているが、それぞれの違いがわからないので調べてみる。
- Observable: いつもの
- Single
- onNext+onComplete = onSuccess でonSuccessは一回しか呼べない
- Maybe
- onSuccessかonErrorかonCompleteのどれかが呼ばれる、または全く呼ばれない
- Completable
- onErrorかonCompleteのどれかが呼ばれる、または全く呼ばれない
エラー処理に関して
エラー処理に関しては↓のように捌けば良さそう。
disposable += ApiClient.createUser()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ res ->
Log.d(TAG, "create user success ${res.id}")
}, { error ->
(error as? HttpException)?.let {
Log.e(TAG, "code: ${it.code()}")
Log.e(TAG, "message: ${it.message()}")
Log.e(TAG, "response: ${it.response()}")
}
})
401が返ってきた場合の実際の出力
E/MainActivity: code: 401
message:
E/MainActivity: response: Response{protocol=h2, code=401, message=, url=https://....}
バッドノウハウ
単純にmoshiを使うだけだと、dataクラスのnon-nullのプロパティにnullが入ってしまう!
参考URL
参考URL
そこでmoshiのkotlin extensionを導入して、non-nullにnullを入れうようとしたら
例外を投げるように修正
例外を投げるように修正
app/build.gradle
に以下を追加implementation 'com.squareup.moshi:moshi-kotlin:1.5.0'
MainActivity
のmoshiを生成している箇所をいかに変更 val moshi = Moshi.Builder()
.add(KotlinJsonAdapterFactory())
.build()
val retrofit = Retrofit.Builder()
.baseUrl(GithubApi.BASE_URL)
.addConverterFactory(MoshiConverterFactory.create(moshi))
.addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
.build()
これでnon-null / null をきっちり管理してくれます
0 件のコメント:
コメントを投稿