一、概念二、添加依赖最新版本[versions] ktor 3.6.0 [libraries] ktor-core { module io.ktor:ktor-client-core, version.ref ktor } #核心库 ktor-okhttp { module io.ktor:ktor-client-okhttp, version.ref ktor } #Android用OkHttp ktor-negotiation { module io.ktor:ktor-client-content-negotiation, version.ref ktor } #内容协商 ktor-serialization { module io.ktor:ktor-serialization-kotlinx-json, version.ref ktor } #序列化 ktor-logging { module io.ktor:ktor-client-logging, version.ref ktor } #日志三、客户端迁移直接复用 OkHttp 设置只需要将 Retrofit 配置的替换掉。object KtorClient { // Json解析 private val json by lazy { Json { prettyPrint true // isLenient true //宽松解析单引号、松散JSON ignoreUnknownKeys true // 忽略接口返回的多余字段服务端新增字段不会导致崩溃容错升级 } } // OkHttp private val okHttp by lazy { OkHttpClient.Builder().build() } // Ktor private val ktor by lazy { HttpClient(OkHttp) { // 内容协商 install(ContentNegotiation) { json(json) // Json解析 } // BaseUrl install(DefaultRequest) { url() } // 引擎 engine { preconfigured okHttp // 用okhttp } } } // ApiService val apiService by lazy { ApiService(ktor) } }四、网络请求迁移从「声明式注解」变成「显式函数调用」。RetrofitKtorGET / POST / PUT / DELETEclient.get() / client.post() / client.put() / client.delete()PathURL 字符串拼接users/$idQueryparameter(key, value)QueryMapparameter()逐个调用或遍历 MapBodysetBody(obj)Headerheader(name, value)Headersheader()多次调用FormUrlEncodedFieldsetBody(FormDataContent(...))或submitForm()MultipartPartsetBody(MultiPartFormDataContent(...))Url直接传完整 URLStreamingprepareGet().execute { }流式读取class ApiService( private val client: HttpClient ) { // 请求方法 }4.1 GET// Retrofit GET(users) suspend fun getUsers(): ListUser // Ktor suspend fun getUsers(): ListUser client.get(users).body()4.2 Path 参数// Retrofit GET(search) suspend fun search( Query(keyword) keyword: String, Query(page) page: Int ): ListResult // Ktor suspend fun search(keyword: String, page: Int): ListResult client.get(search) { parameter(keyword, keyword) parameter(page, page) }.body()4.3 Query 参数// Retrofit GET(search) suspend fun search( Query(keyword) keyword: String, Query(page) page: Int ): ListResult // Ktor suspend fun search(keyword: String, page: Int): ListResult client.get(search) { parameter(keyword, keyword) parameter(page, page) }.body()4.4 POST Body// Retrofit POST(users) suspend fun createUser(Body user: User): User // Ktor suspend fun createUser(user: User): User client.post(users) { contentType(ContentType.Application.Json) setBody(user) }.body()4.5 Header// Retrofit GET(profile) suspend fun getProfile(Header(Authorization) token: String): Profile // Ktor suspend fun getProfile(token: String): Profile client.get(profile) { header(Authorization, token) }.body()4.6 固定 HeaderHeaders// Retrofit Headers(X-Client: android, Accept: application/json) GET(config) suspend fun getConfig(): Config // Ktor suspend fun getConfig(): Config client.get(config) { header(X-Client, android) header(Accept, application/json) }.body()4.7 表单提交FormUrlEncoded// Retrofit FormUrlEncoded POST(login) suspend fun login( Field(username) username: String, Field(password) password: String ): LoginResult // Ktor import io.ktor.client.request.forms.* suspend fun login(username: String, password: String): LoginResult client.submitForm( url login, formParameters parameters { append(username, username) append(password, password) } ).body() // 或者用 setBody suspend fun login(username: String, password: String): LoginResult client.post(login) { setBody(FormDataContent(parameters { append(username, username) append(password, password) })) }.body()4.8 文件上传Multipart// Retrofit Multipart POST(upload) suspend fun upload( Part file: MultipartBody.Part, Part(desc) desc: RequestBody ): UploadResult // Ktor import io.ktor.client.request.forms.* import io.ktor.http.content.* suspend fun upload(fileBytes: ByteArray, fileName: String, desc: String): UploadResult client.post(upload) { setBody(MultiPartFormDataContent( formData { append(desc, desc) append(file, fileBytes, Headers.build { append(HttpHeaders.ContentType, image/jpeg) append(HttpHeaders.ContentDisposition, filename\$fileName\) }) } )) }.body()4.9 完整 URLUrl// Retrofit GET suspend fun getByUrl(Url url: String): Response // Ktor suspend fun getByUrl(url: String): Response client.get(url).body()五、返回值基类