日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Android網絡訪問之Retrofit使用教程_Android

作者:懶到死的程序員 ? 更新時間: 2023-01-11 編程語言

一、概念

HttpClient Android 6中移除(API數量多擴展困難)。
HttpURLConnection 目前官方集成的。
OKHttp Square公司出品,底層通訊的實現。
Retrofit Square公司出品,上層接口的封裝,更方便使用面向對象思維進行網絡操作。

二、使用

Android 9開始默認只允許使用 HTTPS 類型的網絡請求,HTTP明文傳輸因為有安全隱患不再支持。堅持使用的話需要配置:右鍵res目錄→New→Directory→創建一個xml目錄,右鍵xml目錄→New→File→創建一個network_config.xml文件,修改內容如下:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

Manifest {
? ? //添加網絡訪問權限
? ? <uses-permission android:name="android.permission.INTERNET" />
? ? //允許HTTP訪問
? ? <application
? ? ? ? android:networkSecurityConfig="@xml/network_config"
? ? </application>
}

2.1HttpURLConnection

thread {
    var connection: HttpURLConnection? = null
    try {
        val response = StringBuilder()
        val url = URL("https://www.baidu.com")
        connection = url.openConnection() as HttpURLConnection
        connection.connectTimeout = 8000
        connection.readTimeout = 8000
        //GET請求
        val input = connection.inputStream
        val reader = BufferedReader(InputStreamReader(input))
        reader.useLines { response.append(it) }
        print(response.toString())
        //POST請求
        connection.requestMethod = "POST"
        val output = DataOutputStream(connection.outputStream)
        output.writeBytes("username=admin&password=123456")
    } catch (e: Exception) {
        e.printStackTrace()
    } finally {
        connection?.disconnect()
    }
}

2.2OKHttp

傳送門

2.3Retrofit

查看最新版本

implementation 'com.squareup.retrofit2:retrofit:2.9.0' ? ?//會連帶下載 OkHttp和Okio
implementation 'com.squareup.retrofit2:converter-gson:2.k6.1' ? ?//會連帶下載 GSON

2.3.1 定義實體類

根據 JSON 內容,編寫對應的實體類。

data class Person(var name: String, var age: Int)

2.3.2 定義API接口

根據 API 接口,編寫對應的訪問文件。命名通常以功能名稱開頭+Service結尾。

@GET 從服務器獲取數據
@POST 向服務器提交數據
@PUT @PATCH 修改服務器上的數據
@DELETE 刪除服務器上的數據
interface PersonService {
    //接口1:https://www.baidu.com/person.json
    @GET("person.json")    //表示發起的是GET請求,傳入請求的地址(相對路徑,重復根路徑在后面配置)
    fun getPerson(): Call<list<Person>>    //返回值必須聲明成Retrofit內置的Call類型,通過泛型指定服務器返回的具體數據類型
    //接口2:https://www.baidu.com/<page>/person.json
    @GET("{page}/get_data.json")    //使用 {page} 占位
    fun getData(@Path("page") page: Int): Call<Data>    //使用 @Path("page")注解來聲明對應參數
    //接口3:https://www.baidu.com/person.json?u=<user>&t=<token>
    @GET("person.json")
    fun getData(@Query("u") user: String, @Query("t") token: String): Call<Data>
    //接口4:https://api.caiyunapp.com/v2/place?query=北京&token={token}&lang=zh_CN
    @GET("v2/place?token=${GlobalApplication.TOKEN}&lang=zh_CN")    //不變的參數固定寫在GET里
    fun searchPlaces(@Query("query") query: String): Call<PlaceResponse>
    //接口5:https://www.baidu.com/data/<id>
    @DELETE("data/{id}")
    fun deleteData(@Path("id") id: String): Call<ResponseBody>    //該泛型表示能接受任意類型切不會進行解析
    //接口6:https://www.baidu.com/data/create{"id": 1, "content": "The description for this data."}
    @POST("data/create")
    fun createData(@Body data: Data): Call<ResponseBody>    //將Data對象中的數據轉換成JSON格式的文本,并放到HTTP請求的body部分
    //接口7:http://example.com/get_data.json
    //      User-Agent: okhttp    //header參數就是鍵值對
    //      Cache-Control: max-age=0
    //靜態聲明
    @Headers("User-Agent: okhttp", "Cache-Control: max-age=0")
    @GET("get_data.json")
    fun getData(): Call<Data>
    //動態聲明
    @GET("get_data.json")
    fun getData(@Header("User-Agent") userAgent: String, @Header("Cache-Control") cacheControl: String): Call<Data>
}

2.3.3 構建Retrofit對象

val retrofit = Retrofit.Builder()
    .baseUrl("https://www.baidu.com/")    //配置重復的根路徑
    .addConverterFactory(GsonConverterFactory.create())    //指定解析數據使用的轉換庫(這里是Gson)
    .build()

2.3.4 創建API接口實例并調用訪問函數

//創建動態代理對象
val personService = retrofit.create(PersonService::class.java)
//調用訪問函數
personService.getPerson().enqueue(object : Call<List<person>> {    //根據注解中配置的地址進行網絡請求
    override fun onResponse(call: Call<List<person>>, response: Response<List<person>>) {
        val list = response.body()    //得到解析后的對象
    }
    override fun onFailure(call: Call<List<person>>, t: Trouble) {
        t.printStackTrace()
    }
})

2.3.5 優化

object GlobalRetrofit {
    private const val BASE_URL = "www.baidu.com/"
    val retrofit: Retrofit = Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build()
    //fun <T> create(serviceClass: Class<T>): T = retrofit.create(serviceClass)
    inline fun <reified T> create(): T = create(T::class.java)
}
//使用
val personService = GlobalRetrofit.create<PersonService>()

原文鏈接:https://blog.csdn.net/HugMua/article/details/127762176

欄目分類
最近更新