Android+RetrofitでHTTP通信するアプリの作り方(その1)
通信しようと思った時、簡単なものならHTTP APIを自分で処理するのもアリだと思います。
ですが、少し複雑になるとバグが混入しがちだし、潜在的な不具合に怯えながら実装を進めるのは精神的に良くないです。
そこで、ライブラリの力を借りることにします。
今回はRetrofitの力を借りることにします。
目次
記事を書く上で参考にした資料
-
CodeLabs
Retrofitに限らず、androidで何かしようと思っらodeLabsを当たりましょう。大抵書いてあります
-
Retrofitのサイト
本家サイト。
Retrofitとは
https://square.github.io/retrofit/
Retrofit turns your HTTP API into a Java interface.
- HTTP APIがinterfaceになる、ということ
準備
dependency
app/build.gradle.kts
のdependenciesにretrofitを追加します。
dependencies {
...
//retrofit
implementation("com.squareup.retrofit2:retrofit:2.9.0")
...
}
今回はRetrofitでGsonを使うので、それ関連の項目も記述します。
dependencies {
...
//retrofit
implementation("com.squareup.retrofit2:retrofit:2.9.0")
// Gson converter
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
// Gson
implementation("com.google.code.gson:gson:2.10.1")
...
}
Manifest
インターネットへ接続するためのpermission
をManifest
に書かないと、ネットにつながりません。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
...
<!--internet connection -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
...
</manifest>
https://developer.android.com/develop/connectivity/network-ops/connecting
JsonPlaceHolder
サンプルとしてJsonPlaceHolderを利用します。
たとえばhttps://jsonplaceholder.typicode.com/postsにアクセスすると、以下のようなJSONを得ます。
[
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
},
{
"userId": 1,
"id": 2,
"title": "qui est esse",
"body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
}
...
]
これを前提に実装を進めます。
実装
CodeLabs とRetrofitのサイトを参考に実装しています。
data classの定義
上記のJSONに対応するdata classを定義します。
観察すると、下記のような構造のオブジェクトがアレイになっていることがわかります。
Key | Type |
---|---|
userId | Int |
id | Int |
title | String |
body | String |
このオブジェクトに対応するdata class
を定義します。
data class Post(
val userId: Int,
val id: Int,
val title: String,
@SerializedName("body")
val text: String
)
各引数名と各Key名は一致させます。
それができない、あるいは避けたい場合には@SerializedName
を使って読み替えます
今回body
をtext
に読み替えているのは、HTMLのbody
と紛らわしいためです。
Retrofitのインスタンス
Retrofit.Builder()
を使います。
private val retrofit = Retrofit.Builder()
.baseUrl("https://jsonplaceholder.typicode.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
この例ではconverter
としてGsonConverterFactory
を使用しています。
interfaceの定義
interfaceには@GET
アノテーションをつけた関数が必要です。
interface JsonPlaceHolderAPI {
/**
* 全ての記事を取得する
*/
@GET("posts")
suspend fun getPosts(): List<Post>
}
この関数の定義からいくつか読み取れる事柄があります
- エンドポイントとして
post
を指定していること -
suspend
関数であること -
Post
のリストを返すこと
interfaceのインスタンス化
Retrofitのインスタンスを通じて取得します。
val jsonPlaceHolderAPI = retrofit.create<JsonPlaceHolderAPI>()
実行
override fun onResume() {
super.onResume()
lifecycleScope.launch {
val postList = jsonPlaceHolderAPI.getPosts()
val text = "postList size is ${postList.size}"
Log.d(TAG, "onResume: $text")
}
}
suspend関数なのでlifecycleScopeから実行しています。
- suspendを使いたくない、使えない場合は、
enqueue
を使えます。enqueue
ではCallback
で結果を得ます
結果はLogCat
に出力されます。
リポジトリ
https://github.com/aburagirio/retrofitExample.git
ブランチpart1
をcheck outしてください。