【问题标题】:Android/Kotlin - okhttp4 GET request - return response headers and not follow redirectAndroid/Kotlin - okhttp4 GET 请求 - 返回响应标头而不遵循重定向
【发布时间】: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,但我没用过,所以帮不上忙

标签: android kotlin okhttp


【解决方案1】:

我想通了。与 iOS 不同的是,您可以直接在回调线程中更新 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. The function updates the TextView itself
            makeRequest(appLinkData)
        }
    }

    // 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 locationURL = response.headers["Location"]
                if (locationURL != null) {
                    Log.i("locationURL", locationURL)
                    // Show this on our simple example app
                    val originalUrl : TextView = findViewById(R.id.originalURL)
                    originalUrl.text = locationURL
                }
            }
        })
    }
}

.gif of app running

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-28
    • 2019-07-17
    • 2019-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-06
    • 2019-01-19
    相关资源
    最近更新 更多