用來做網路請求的第三方 library
原生的網路請求方法為使用 HttpURLConnection 和 HttpClient,使用起來較為複雜,
第三方即是將複雜的部份封裝起來,讓我們更方便使用。
除了這次使用的 OkHttp 以外,Google 也有推出 Volley 這個第三方,可以做簡單的 HTTP Request
要使用 OkHttp 這個第三方 library 要先在 Gradle 加入
compile 'com.squareup.okhttp3:okhttp:3.11.0'
實例化一個 Client
val okHttpClient = OkHttpClient()
建立 Request
最基本的請求有 GET 方法和 POST 方法兩種(關於 HTTP 請求可參考 參考資料)
需看該 API 要求用什麼方法做請求來建立相應的 Request
兩種 Request 建立的方法有些許不同
GET 方法
不需要傳送資料,直接透過請求的 API 網址取得需要的資料
(關於 GET 方法可參考 Day 5 內容)
因為不需要傳送資料,因此建立 Request 只需要加入 API 網址即可
Request.Builder()
.url(URL)
.build()
val request = Request.Builder() // 實例化一個 Builder
//加上要發送請求的 API 網址
//name 為傳入的參數
.url("https://api.github.com/users/$name")
//建立 Request
.build()
POST 方法
需要傳送資料讓 API 知道我們想要取得哪些資料
因此建立 Request 時除了加入 API 網址外,還需加入我們要傳送的資料,
而我們要傳送的資料格式及內容也需對應 API 要求的格式及內容。
首先先建立我們要傳送的資料,以 JSON 形式和 FormBody 形式為例:
JSON 形式
RequestBody.create(JSON, jsonString)
JSON:表示為 JSON 形式。
jsonString:內容,為 JSON 格式的字串。
(關於 JSON 格式會在後面做介紹)
例如:
val json = {"name": "Aria", "num": 1000}
val body = RequestBody.create(JSON, json)
FormBody 形式
FormBody.Builder()
.add(Key, Value)
.build( )
例如:
val body = FormBody.Builder()
.add("username", Data.username)
.add("account", Data.account)
.add("password", Data.password)
.add("email", Data.email)
.add("phone", Data.phone)
.build()
建立完要傳送的資料後就可以建立 Request
在建立 Request 時加入建立好的資料以及 API 網址
Request.Builder()
.url(URL)
.post(body)
.build( )
例如:
val request = Request.Builder()
.url("https://api.github.com/repos/UserName/RepositorieName/issues")
.post(body)
.build()
取得 Client 中的 Call 對象並帶入建立好的 Request
newCall (request: Request)
val call = client.newCall(request)
執行請求
執行請求有分為同步請求與異步請求
兩種請求方式的使用差異可以參考 參考資料1 參考資料2
關於兩種請求方式的源碼解析可以參考 參考資料
同步請求
直接執行 Call 的 execute 方法,可得到回傳的 Response
execute () : Response
#此方法會由呼叫 execute 方法的執行緒來執行網路請求
由於執行網路請求為耗時工作,若由主執行緒來執行會使主執行緒停擺,
因此需要另開執行緒來呼叫 execute 方法並執行網路請求。
(關於執行緒可以參考 官方參考資料)
Thread(Runnable{
val response = call.execute()
})
異步請求
執行 Call 的 enqueue 方法,需帶入 Callback 處理回傳結果
enqueue(callback: Callback)
#此法 OkHttp 會自己產生一個 Thread,並在裡面執行 Call 的 execute 方法。
因此不需要自己另開 Thread 來執行請求,Callback 也會在該 Thread 中執行,
若需變更 UI 介面就需要用 runOnUiThread 方法由主執行緒處理。
call.enqueue(object : Callback {
override fun onFailure(call: Call?, e: IOException?) {
println("fail : $e")
}
override fun onResponse(call: Call?, response: Response?) {
//處理回來的 Response
})
處理回來的 Response
通常我們需要的資訊會在 Response 的 body() 中
並且為 JSON 格式(JSONObject 或 JSONArray)
將 Response 的 body() 轉為字串(會變成符合 JSON 格式的字串)
// response 為同步請求回傳的 Response
// 或異步請求成功時 Callback 中 onResponse 方法帶回的 Response
val responseStr = response!!.body()!!.string()
將符合 JSON 格式的字串轉為 JSONObject 或 JSONArray
(看傳回的資料格式是 JSONObject 或 JSONArray)
// 若為 JSONObject
val itemList = JSONObject(responseStr)
// 若為 JSONArray
val itemList = JSONArray(responseStr)
用 JSONObject 及 JSONArray 的 get 方法取出想要的資料
JSONObject
用 Key 取出對應的資料
JSONObject.get(Key: String)
JSONArray
用位置取出對應的資料
JSONArray.get(index: Int)
Android
Kotlin
OkHttp