開一個採用Empty Activity 的 Kotlin專案
簡單建專案的影片 (QwQ) b 影片連結,但這是配置Anko的Kotlin專案。
AndroidManifest.xml
因為OkHttp需要網路權限,所以添加uses-permission
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.useokhttptowin">
...
<uses-permission android:name="android.permission.INTERNET"/>
...
</manifest>
準備環境(使用Gradle)
我們會用到Anko的doAsync 和OkHttp的函式庫。
所以在build.gradle(Project:專案名稱)的buildscript{}裡面添加 !
ext.anko_version='0.10.4'
將底下的字串貼在你的build.gradle(Module: app)裡面添加 !
dependencies {
...
compile "org.jetbrains.anko:anko:$anko_version"
compile 'com.squareup.okhttp3:okhttp:3.9.1'
}
修改完,別忘了要點右上角的 "Sync Now"
自訂類別
建一個叫做KuRequest的類別來封裝我們的OkHttp, 否則內容全寫在MainActivity.kt裡面開發會非常凌亂!
我們先寫個類別架構,再來說明。
// KuRequest.kt
package com.example.useokhttptowin
import okhttp3.OkHttpClient
import okhttp3.Request
class KuRequest {
private val client = OkHttpClient()
// 發送一個get請求
fun get(url: String): String? {
// 暫時留空
}
}
這個KuRequest類別非常簡單,就一個屬性 和 一個方法。
OkHttpClient()我們因為將在這個類別中多次用到, 所以就先將它賦值給client變數。
get方法(詳細定義!)
撰寫負責發送get的Http請求, 並返回Http響應的結果(一個可能為null的字串),
// 發送一個get請求
fun get(url: String): String? {
val request = Request.Builder()
.url(url)
.build()
val response = client.newCall(request).execute()
return response.body()?.string()
}
request
用Request.Builder()建立一個http的request, 後面連接url()方法指定他的URL, 最後連接build()方法真正建立一個OkHttp的Request。
response
使用client.newCall()添加我們request變數, 並且後面連接execute()方法,將執行我們的Http請求回傳應結果。
值得注意的是execute是同步執行,OkHttp另外還有一個enqueue的異步方法 (可參考...篇章)
return
response.body()會返回一個ResponseBody的值 (可能為null) ResponseBody內部有一個string()方法會返回一個字串 ,該字串是解碼於Http標頭中的"Content-Type"欄位。
p.s. 因為我body()可能回傳null, 我們這裡可以使用?.來操作string()方法, 即使是null也能安全呼叫方法,這算是Kotlin的特色Safe Calls。
使用自訂類別 (KuRequest)
切換到MainActivity.kt 在onCreate() 內部添加4行程式碼!
val testJsonUrl = "https://jsonplaceholder.typicode.com/posts"
val kuRequest = KuRequest()
val jsonStr = kuRequest.get(testJsonUrl)
println("jsonStr = $jsonStr")
然後執行,就是會跳出一個例外錯誤!! android.os.NetworkOnMainThreadException
這個導致例外的原因是因為在安卓MainThread不能執行網路功能, 所以必須要用不同的執行緒執行Http請求!
改用異步呼叫的方法
這也是為什麼要用Anko的關係,它讓你能輕鬆用doAsync實現異步。
val testJsonUrl = "http://jsonplaceholder.typicode.com/Users"
val kuRequest = KuRequest()
doAsync {
val jsonStr = kuRequest.get(testJsonUrl)
println("jsonStr = $jsonStr")
}
結果(印出JSON字串)
可能出現的錯誤!
如果是出現上方反藍的字串結果,應該是底下三種情形
可能是執行程式的手機或模擬器的網路或Wifi沒連接。
或是上方Manifest的部分你沒有添加好 uses-permission。
再來就是真的那個網站連結掛掉or有誤,所以程式無法去找到它!...QwQ
那下一章將會提到如何處理JSON字串。
參考
完整專案
OkHttp官網 http://square.github.io/okhttp/
Anko官方Github https://github.com/Kotlin/anko