取得網路權限
在 AndroidManifest.xml 宣告需要使用到網路權限:
<uses-permission android:name="android.permission.INTERNET" />
加入依賴套件
在 build.gradle(Module :app) 中加入 Retrofit 套件,和 gson 解析回應內容的轉換套件
dependencies {
implementation "com.squareup.retrofit2:retrofit:2.9.0"
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
}
讀取資料
建立回應實體
本次讀取的範例資料是 JSON Placeholder 服務的測試資料,連結是 https://jsonplaceholder.typicode.com/posts ,使用 Http Get ,不用提供參數,範例回應內容如下:
[
{
"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"
}
]
先依據回應內容建立對應的資料類別:
import com.google.gson.annotations.SerializedName
data class Post(
@SerializedName("userId") val userId: Int,
@SerializedName("id") val id: Int,
@SerializedName("title") val title: String,
@SerializedName("body") val body: String
)
SerializedName 是 gson 提供的註解(annotations),用來將 json 的屬性和類別的屬性對應,如果本身屬性名稱一樣就可以省略,是名稱不同的時候才需要使用 SerializedName 映射屬性。
建立服務
建立 JsonPlaceholderService 服務類別,通常會建立一個 network package 放在這裡面。此 Service 是用來對應 api
import retrofit2.Call
import retrofit2.http.GET
interface JsonPlaceholderService {
@GET("posts")
fun getPosts(): Call<List<Post>>
}
建立請求服務
val retrofit = Retrofit.Builder()
.baseUrl("https://jsonplaceholder.typicode.com/") // API 網址
.addConverterFactory(GsonConverterFactory.create()) // 使用 Gson 解析回應內容
.build()
val jsonPlaceholderService = retrofit.create(JsonPlaceholderService::class.java)
呼叫 API
實際呼叫 API:
jsonPlaceholderService.getPosts().enqueue(object : retrofit2.Callback<List<Post>> {
override fun onResponse(
call: retrofit2.Call<List<Post>>,
response: retrofit2.Response<List<Post>>
) {
val posts = response.body() ?: return
for (post in posts) {
Log.i("GetDataButton", "post.id: ${post.id}")
Log.i("GetDataButton", "post.userId: ${post.userId}")
Log.i("GetDataButton", "post.title: ${post.title}")
Log.i("GetDataButton", "post.body: ${post.body}")
Log.i("GetDataButton", "--------")
}
}
override fun onFailure(call: retrofit2.Call<List<Post>>, t: Throwable) {
Log.i("GetDataButton", "onFailure: ")
}
})
帶入參數
上面的連結是 https://jsonplaceholder.typicode.com/posts ,如果要在後面帶入參數,變成 https://jsonplaceholder.typicode.com/posts/1 ,則可以使用下列方式執行:
import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Path
interface JsonPlaceholderService {
@GET("posts")
fun getPosts(): Call<List<Post>>
@GET("posts/{id}")
fun getPostById(@Path("id") postId: Int): Call<Post>
}
jsonPlaceholderService.getPostById(1).enqueue(object :retrofit2.Callback<Post>{
override fun onResponse(call: retrofit2.Call<Post>, response: retrofit2.Response<Post>) {
val post = response.body() ?: return
Log.i("GetDataButton", "post.id: ${post.id}")
Log.i("GetDataButton", "post.userId: ${post.userId}")
Log.i("GetDataButton", "post.title: ${post.title}")
Log.i("GetDataButton", "post.body: ${post.body}")
Log.i("GetDataButton", "--------")
}
override fun onFailure(call: retrofit2.Call<Post>, t: Throwable) {
Log.i("GetDataButton", "onFailure: ")
}
})
參考資料:
Retrofit
留言
張貼留言
如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com