どろあそび (8)

Android Kotlin の基礎」レッスン8はネットワークからのデータおよび画像の取得と画像表示を扱っています。

現在、ネットワークサービスはhttpを使用したものが主流になっています。このレッスンではhttpを使用したサービスアクセスの例としてRESTでアクセスしJSONで応答が記述されるサービスへのアクセスを扱っています。

といってもRESTやJSONを直接扱うのではなくRetrofitとMoshiというライブラリを使用するのでネットワークアクセスの詳細は隠蔽され、これらに関する知識は基本的には必要ありません (といっても、httpの最小限の知識は必要になります)。

また、画像データの受信と表示としてGlideライブラリを使用する例もこのレッスンで扱っています。

ところで、レッスン8のサンプルプログラムはAndroid Studioの現行版 (Arctic Fox) ではコンパイルできません。例によってbuild.gradleに記載されているライブライバージョンを最新のものに更新するとともにnavigationをandroid.arch.navigationからandroidx.navigationに変更する必要があります。

ということでレッスン項目を見ていきます。

最初の項目「Getting data from the internet」はRetrofitとMoshiによるネットワークサービスからのデータ取得を扱います。

まずRetrofit.Builderに応答を処理するコンバーターとベースURLを渡してRetrofitのインスタンスを作成し、@GETアノテーションでhttp get要求するリソースと対応するKotlin関数を関連付けたインターフェースを定義することでサービスへのアクセスを可能とします。

なお、サービスアクセスを初期化するには時間がかかるため、by lazyを初期化子に指定して、最初の呼び出しが行われるまで初期化を遅延するよう指示します。

「by lazy」はちょっと気持ち悪いので後で調べた方がよさそうです。

続いてJSONによる応答のMoshiライブラリを使用した処理を行います。

Moshiは受信したJSON形式の応答データから対応するデータクラスのインスタンスを生成するもので、応答に含まれる名前とフィールド名 (もしくは@Jsonアノテーションで指定された名前) が一致するフィールドに応答データを記録します (レフレクションを思いっきり使ってるなと思わせる仕様です)。

RetrofitにはMoshiに対応したコンバーターが用意されているので、Retrofitに指定するインターフェースの戻り値型を作成したデータクラスのListとすることでJSONに対応したネットワークサービスアクセスが可能となります。

また、Retrofitはコルーチンに対応しているので、インターフェースのKotlin関数にsuspendを指定し、Kotlin関数呼び出し時にlaunchすることで時間のかかるネットワークアクセスをメインスレッドから切り離すことができます。

2番目の項目「Loading and displaying images from the Internet」はGlideライブラリを使用したネットからの画像の取得と表示を扱います。

まず、URL文字列からUriオブジェクトを生成して取得先とし、取得した画像の表示先としてImageViewを指定すると指定されたImageViewに受信した画像が表示されます。

さらに受信中を示すアニメーション画像やエラーを示す画像を指定することもできます。

単にWebサーバーから画像を取得して画面に表示するだけであればGlideを使用することで割と簡単に表示できることがわかります。

3番目の項目「Filtering and detail views with internet data」はRetrofitでクエリ文字列を指定する方法を扱っている。

RetrofitでURLのクエリ文字列を指定する場合は、インターフェースのKotlin関数引数に@Queryアノテーションを付加することで実現できます。

また、この項目ではMoshiで処理したデータを変換するための方法が扱われています。

MoshiはJSONで記述された応答データをKotlinのデータクラスに変換しますので、応答データを処理した結果を出力する場合は外部で変換を行うか、変換結果で初期化された値をデータクラスが保持している必要があります。

しかし、データクラスに変換結果で初期化された値を定義するとシリアル化できなくなるため、フラグメントに引数として渡すことができなくなります。

これを解決するため、データクラスにParcelableインタフェースを適用し、@Parcelizeアノテーションを設定し、データクラスをシリアル化 (梱包) できるようにします。

ところで、このレッスンでは「kotlinx.android.parcel.Parcelize」をインポートするよう指示されていますが、現在は「kotlinx.parcelize.Parcelize」をインポートしないと正しく動作しないようです。

以上、ネットワークサービスからのデータ受信と処理はネットワークサービスの側が適切に対応していれば (JSONなどRetrofitが用意しているコンバーターに対応した応答を返せば、そして単純なクエリ文字列で要求ができれば)、割と簡単に実装できそうです。


bewise.jp

Be Wise: 賢くなろうということ

0コメント

  • 1000 / 1000