【发布时间】:2020-10-27 05:17:32
【问题描述】:
我正在 Android Kotlin 中发出 GET 请求。下面的代码是一个基本的起点。响应返回“302 Found”重定向,并且代码在响应标头中获得Location。
我从 volley 开始,并在研究了下面 cmets 中提到的替代方案后切换到 https://square.github.io/okhttp/,感谢 R'Js 的帮助。
在build.gradle:
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
网络部分现在正在工作。异步/回调似乎是必要的,因为在 MainActivity 中开始执行(如https://square.github.io/okhttp/recipes/#asynchronous-get-kt-java 中所述):
我现在想取回标头值以在正确的范围内以某种方式更新TextView。也许我需要
- 创建另一个回调来更新它,或者
- 将句柄传递给 TextView 并在现有回调中完成工作
- 还有别的吗?
package com.example.testlinks
// Example deep linking app
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import okhttp3.*
import java.io.IOException
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
handleIntent(intent)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
Log.i("MainActivity", "onNewIntent called")
handleIntent(intent)
}
private fun handleIntent(intent: Intent) {
Log.i("MainActivity", "handleIntent called")
val appLinkAction = intent.action
val appLinkData: Uri? = intent.data
if (Intent.ACTION_VIEW == appLinkAction) {
// handle URL
val res : TextView = findViewById(R.id.result)
res.text = appLinkData.toString()
// Show this on our simple example app
val location = makeRequest(appLinkData)
val originalUrl : TextView = findViewById(R.id.originalURL)
}
}
// Basic URL GET request.
// See https://guides.codepath.com/android/Using-OkHttp
// https://square.github.io/okhttp/recipes/
private fun makeRequest(url : Uri?) {
// More efficient click-tracking with HTTP GET to obtain the "302" response, but not follow the redirect through to the Location.
val client = OkHttpClient.Builder()
.followRedirects(false)
.build()
val request = Request.Builder()
.url(url.toString())
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
val originalURL = response.headers["Location"]
if (originalURL != null) {
println(originalURL) // TODO: pass value back to calling function
}
}
})
}
}
【问题讨论】:
-
你为什么使用 Volley?我建议你使用 HttpUrlConnection 甚至更好 - Retrofit 2
-
啊。我使用它是因为这里的官方文档中推荐了它。 developer.android.com/training/volley。除了基本的培训材料之外,Kotlin 的图书馆参考资料似乎很差(与 Golang 相比),图书馆的可发现性也很差。将在 Retrofit 2 周围戳一下。
-
当我第一次开始制作安卓应用程序时,我使用了 HttpUrlConnection,它很容易上手,因此我建议先尝试一下。改造相当困难,因为它使用了更高级的东西,比如
Annotations,至少从我个人的经验来看,一开始有点难以掌握。尝试看看改造,如果你觉得很难,只需使用 HttpUrlConnection 一段时间,你会没事的,直到你对 Kotlin 和 Android 开发有更深入的了解。 -
hmm Retrofit 2 似乎适用于具有 API 的客户端,其中解析返回的 JSON 是主要任务。 OKHttp(它是 Retrofit 的基础,也是由 square.io 发布的)在这里看起来是一个更好的选择? square.github.io/okhttp/recipes 同样,所有文档似乎都是“示例”而不是参考资料。
-
它确实可以更好地使用 API 进行优化,但是,您可以获得简单的字符串响应,并从那里做任何您需要的事情。使用 ScalarsConverterFactory 和 Response
作为返回参数。你也可以试试 okhttp,但我没用过,所以帮不上忙