開一個採用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字串)

可能出現的錯誤!

如果是出現上方反藍的字串結果,應該是底下三種情形

  1. 可能是執行程式的手機或模擬器的網路或Wifi沒連接。

  2. 或是上方Manifest的部分你沒有添加好 uses-permission。

  3. 再來就是真的那個網站連結掛掉or有誤,所以程式無法去找到它!...QwQ

那下一章將會提到如何處理JSON字串。

參考

完整專案

OkHttp官網 http://square.github.io/okhttp/

Anko官方Github https://github.com/Kotlin/anko

results matching ""

    No results matching ""