RetrofitとOkHttpを使ってWebAPIを呼び出します。
今回利用するAPIはQiitを使います
https://qiita.com/api/v2/items?page=1&per_page=20
極力コメントアウトして、何が書かれているか残しときました。
#RetrofitとOkhttpとは
RetrofitはOkHttpラッパーでありHTTPクライアントを実装する際によく利用されます。
最近のサービスで通信が必要な処理を実装する時はほとんど使われているそうです。
HTTP通信を実装する際にコールバックの処理を書きやすくします。
#手順
1.gradleとManifest
2.interface
3.Model
4.クライアント
5.呼び出し
#1.gradleとManifest
Gradle Scriptsのbuild.gradle(Module.app)の所にライブラリ導入
dependencies{
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
//書き方として以下もある
//def retrofitVersion = '2.9.0'
//implementation 'com.squareup.retrofit2:retrofit:$retrofitVersion'
//implementation 'com.squareup.retrofit2:converter-gson:$retrofitVersion'
}
今回ネットワークを利用した通信なのでAndroidManifestに以下を記入
<manifest xmlns:android=
~省略
//以下を記入
<uses-permission android:name="android.permission.INTERNET"/>
<application
//~省略
#2.interface
今回は HTTP の GET メソッドを使うため@GET をつけました。
interface ApiService {
//パラメータの前までをここに書く
@GET("api/v2/items")
//呼び出す際に必要なリクエストURLのパラメータの設定
fun apiDemo(
@Query("page") page: Int,
@Query("par_page") perPage: Int
): Call<List<QiitResponse>>
}
#3.Model
APIから取り出したいデータを格納するデータクラス
//後に欲しいデータを取得する際に必要となる箱
data class QiitResponse(
val url: String?,
val title: String?,
val user: User?
)
//階層が分かれている時は分ける
data class User(
val id: String?
)
実際に表示する際に必要となるクラス
class Model {
var title: String? = null
var id: String? = null
var url: String? = null
}
#4.クライアント
//Clientを作成
val httpBuilder: OkHttpClient.Builder get() {
//httpClinetのBuilderを作る
val httpClient = OkHttpClient.Builder()
//create http client headerの追加
httpClient.addInterceptor(Interceptor { chain ->
val original = chain.request()
val request = original.newBuilder()
.header("Accept", "application/json")
.method(original.method(), original.body())
.build()
//proceedメソッドは再びパーミッション許可ダイアログを表示してその結果を返します
var response = chain.proceed(request)
return@Interceptor response
})
.readTimeout(30, TimeUnit.SECONDS)
//log
val loggingInterceptor = HttpLoggingInterceptor()
loggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
httpClient.addInterceptor(loggingInterceptor)
return httpClient
}
//繋ぎこみ
fun createService(): ApiService {
var client = httpBuilder.build()
var retrofit = Retrofit.Builder()
.baseUrl("https://qiita.com/")//基本のurl設定
.addConverterFactory(GsonConverterFactory.create())//Gsonの使用
.client(client)//カスタマイズしたokhttpのクライアントの設定
.build()
//Interfaceから実装を取得
var API = retrofit.create(ApiService::class.java)
return API
}
#5.呼び出し
//データリストに保存し、そのデータの取得
fun fetchAllUserData(): List<Model> {
val dataList = mutableListOf<Model>()
//リクエストURl作成してデータとる パラメータの引数の設定も行う
Retrofit.createService().apiDemo(page = 1, perPage = 20).enqueue(object : Callback<List<QiitResponse>> {
//非同期処理
override fun onResponse(call: Call<List<QiitResponse>>, response: Response<List<QiitResponse>>) {
Log.d("TAGres","onResponse")
//ステータスコードが200:OKなので、ここではちゃんと通信できたよ
if (response.isSuccessful) {
response.body()?.let {
for (item in it) {
val data: Model = Model().also {
//取得したいものをAPIから手元のリスト(Model)に
it.title = item.title
it.url = item.url
it.id = item.user!!.id
}
//取得したデータをModelに追加
dataList.add(data)
}
//今回recyclerViewを利用しているが、これを書かないと先に画面の処理が終えてしまうので表示されなくなります。
recyclerView.adapter?.notifyDataSetChanged()
}
} else {
}
}
override fun onFailure(call: Call<List<QiitResponse>>, t: Throwable) {
Log.d("TAGres","onFailure")
}
})
return dataList
}
Okhttpを利用するとonResponseとonFailureでコールバックを用いた非同期通信が利用できる。
#終わりに
初めてのAPIの周りなのでもっとうまく書ける方法はあると思いますが、自分がわかるようにまとめました。
1つの参考資料になってくれたら嬉しいです。
また、何か違う部分ありましたら、コメントいただけると嬉しいです。
次はMoshi、RxJavaを取り入れてみたいです。