アプリを作ることになったのだが、とりあえず練習がてら何かのApiを叩いてJSONをパースしてlistを表示できればOKだったので、qiitaのApiを叩いて表示してみました。
Android studio 3.2.1を使って開発しましたが、android開発は初めてなのでこれでいいのかよくわからず…
githubはこちら
ライブラリなど
build.gradle
def retrofitVersion = '2.4.0'
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
implementation "com.squareup.retrofit2:adapter-rxjava:$retrofitVersion"
implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion"
implementation 'com.squareup.okhttp3:logging-interceptor:3.8.1'
デバッグ時のloggerがあるとすごく開発が捗るので入れてよかったです。
app/src/main/AndroidManifest.xml
+ <uses-permission android:name="android.permission.INTERNET" />
これをいれないとApiをたたけないです
modelなど
models/item.kt
data class Item(var id: String,
var title: String,
var url: String)
Interfaces/ItemInterface.kt
import retrofit2.http.GET
import retrofit2.Call
import retrofit2.Retrofit
import ml.okbm.qiita_app.models.Item
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.converter.gson.GsonConverterFactory
interface ItemInterface {
@GET("v2/items.json")
fun items(): Call<List<Item>>
}
fun createService(): ItemInterface {
val baseApiUrl = "https://qiita.com/api/"
val httpLogging = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
val httpClientBuilder = OkHttpClient.Builder().addInterceptor(httpLogging)
val retrofit = Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(baseApiUrl)
.client(httpClientBuilder.build())
.build()
return retrofit.create(ItemInterface::class.java)
}
tokenを使った認証をしていないので、1時間に60回しか叩けません。
Qiita API v2ドキュメント - Qiita:Developerに詳しく書いてます。
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import ml.okbm.qiita_app.Interfaces.createService
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import android.util.Log
import android.widget.ArrayAdapter
import android.widget.ListView
class MainActivity : AppCompatActivity() {
// interfaceという名前微妙だがサンプルなので我慢
private val itemInterface by lazy { createService() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
fetchItems()
}
private fun fetchItems() {
itemInterface.items().enqueue(object : Callback<List<Item>> {
override fun onFailure(call: Call<List<Item>>?, t: Throwable?) {
Log.d("fetchItems", "response fail")
Log.d("fetchItems", "throwable :$t")
}
override fun onResponse(call: Call<List<Item>>?, response: Response<List<Item>>) {
if (response.isSuccessful) {
response.body()?.let {
Log.d("fetchItems", "response success")
var items = mutableListOf<String>()
for (item in it) {
items.add(item.title)
}
val adapter = ArrayAdapter<String>(this@MainActivity, android.R.layout.simple_list_item_1, items)
val list: ListView = findViewById(R.id.list_item);
list.adapter = adapter
}
}
Log.d("fetchItems", "response code:" + response.code())
Log.d("fetchItems", "response errorBody:" + response.errorBody())
}
})
}
}
apiのレスポンスが以下のようになっているため、responseを<List<Item>>
にしています。
[
{
"response_body": xxx,
"id: xxx,
}
]
また結構ログを入れたままにしているのは確認のためなので、必要なかったら切ってもらってもいいかもですね。
最初reuqestしてるURLを見たかったので入れてて便利だったのでそのまま残しちゃいましたが。。。
listはもっと凝った作りにして、DataBindingを使ったやり方にしないとだめそうなんだけど、一旦ここで終わり。