あれだけ複雑だった処理があら簡単です。
RxJava2を利用すると非同期処理が簡単に実現できる。Androidでは、UI部品などが動作するメインスレッドで通信をしようとすると怒られる。そのため別スレッドで実行するために様々な方法があるが、その方法は結構面倒であることが多い。
しかし、RxJava2を利用すると、簡単に非同期処理ができるし、UI部品が動作するメインスレッドに動作を記述することができ、また簡単にメインスレッドでimageViewに表示することができる。
okHttp3の詳細については、こちらを参照して欲しい。RxJava2による非同期処理の基本はこちらを参照して欲しい。
以下、コメントとして説明しているので読んでみて欲しい。
お決まりの設定。
RxJava2を利用すると非同期処理が簡単に実現できる。Androidでは、UI部品などが動作するメインスレッドで通信をしようとすると怒られる。そのため別スレッドで実行するために様々な方法があるが、その方法は結構面倒であることが多い。
しかし、RxJava2を利用すると、簡単に非同期処理ができるし、UI部品が動作するメインスレッドに動作を記述することができ、また簡単にメインスレッドでimageViewに表示することができる。
okHttp3の詳細については、こちらを参照して欲しい。RxJava2による非同期処理の基本はこちらを参照して欲しい。
以下、コメントとして説明しているので読んでみて欲しい。
お決まりの設定。
//まずはgradleに今回使用するライブラリを登録しておく
implementation 'io.reactivex.rxjava2:rxjava:2.1.14'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
//マニフェストファイルで通信する許可を得ておく
<uses-permission android:name="android.permission.INTERNET" />
以下が、今回のサンプルコード
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//URLなどアクセス先の情報などを登録しておく
val request: Request = Request.Builder().let {
//フリー画像サイトの画像への直リンクです
it.url("https://www.pakutaso.com/shared/img/thumb/nuko-8_TP_V1.jpg")
it.get()
it.build()
}
//RxJava関連の処理を記述
//今回は値が1回だけ返ればいいのとエラー処理をしたいのでSingleを利用する
//返値はBitmapを設定する
var single = Single.create<Bitmap> {
//この処理は別スレッドで動作する
try {
//通信してデータを取得する
//execute()はokHttpClientのインスタンスを生成したスレッドで動作する
//そのためメインスレッドでexecuteするとメインスレッドでやるなと叱られる
//しかしここはRxJava2により非同期処理されるのでexecuteでも問題がない
val response: Response = OkHttpClient().newCall(request).execute()
if (response.isSuccessful) {
//受信したデータをBitmapに変換して成功として返す
it.onSuccess(BitmapFactory.decodeStream(response!!.body()!!.byteStream()))
} else {
//失敗していたら失敗であるとエラーを報告する
//今回はエラー処理については記述していない
it.onError(Throwable("fail"))
}
} catch (e: Exception) {
//処理自体に失敗していたらエラー報告
it.onError(Throwable("error"))
}
}
//特に何も無ければ新しいスレッドで処理をするという記述
//Createの部分がこのスレッドで動作する
.subscribeOn(Schedulers.newThread())
//これ以降のメソッドチェーンの処理はメインスレッドで行うという記述
.observeOn(AndroidSchedulers.mainThread())
.doOnSuccess {
//onSuccessを実行するとここの処理が実行される
//Bitmapが返ってくるので、imageViewに表示させる
//ここはメインスレッドなのでUI部品への操作が可能
ivImageView.setImageBitmap(it)
}
btnButton.setOnClickListener {
//ボタンクリックで非同期処理の開始
single.subscribe({}, {})
}
}
}