首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android -更新-基本Url中缺少的查询参数

Android -更新-基本Url中缺少的查询参数
EN

Stack Overflow用户
提问于 2019-03-20 09:01:51
回答 3查看 1.7K关注 0票数 1

我正在开发一个使用Dagger2 + Retrofit + RxAndroid + OkHttp3 +组件的安卓应用程序。Min = 16

问题:在API 16上运行应用程序时,Url生成是不正确的。Url缺少我通过Retrofit传递的@QueryMap参数。同样,当我在api级别21+上测试应用程序时,效果也很好。

更正url - on api 21+ - "http://api.apixu.com/v1/forecast.json?q=IDR&days=10&key=apikey

在api 16/19上生成的url - "http://api.apixu.com/v1/forecast.json

改装接口-

代码语言:javascript
复制
@GET("forecast.json")
fun fetchWeatherDetails(
    @QueryMap hashMap: @NotNull HashMap<String, String>
): @NotNull Observable<ApiResponse>

改造建造者-

代码语言:javascript
复制
val httpClient = getOkHttpClient()
    return Retrofit.Builder()
        .baseUrl(apiBaseUrl)
        .addConverterFactory(GsonConverterFactory.create())
        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
        .client(httpClient)
        .build()

OkHttpClient -

代码语言:javascript
复制
val builder = OkHttpClient.Builder()
    builder
        .cache(cache)
        .connectTimeout(60, TimeUnit.SECONDS)
        .readTimeout(60, TimeUnit.SECONDS)
        .followRedirects(true)
        .followSslRedirects(true)

    val httpLoggingInterceptor = HttpLoggingInterceptor()

    if (BuildConfig.DEBUG) {
        httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BODY
    } else {
        httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.NONE
    }

    builder.addInterceptor(HeaderInterceptor())
        .addInterceptor(httpLoggingInterceptor)
    return builder.build()

自从我被困在这个问题上已经超过两天了。任何帮助都将不胜感激。

更新: Api查询代码在API 21+上运行良好。

API-16和API-19失败。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-03-20 09:37:21

很明显,您的URL没有编码,因此您需要确保它在所有平台上都使用@QueryMap(encoded = true)进行编码。

如果不成功,恐怕需要手动使用自定义拦截器对类似于%3F?等字符进行编码,例如:

代码语言:javascript
复制
@Override
    Response intercept(Interceptor.Chain chain) throws IOException {
        Request request = chain.request()
        def string = request.url().toString()
        string = string.replace("%26", "&")
        string = string.replace("%3D", "=")
        string = string.replace("%3F", "?")

        Request newRequest = new Request.Builder()
            .url(string)
            .build()

        return chain.proceed(newRequest)
    }

参考资料:

票数 1
EN

Stack Overflow用户

发布于 2019-03-20 11:16:42

请阅读OkHttp Requirements一节:它字面上只提到3.12.x分支支持Android (APILevel9+)和Java7+。对于设备< API 21缺乏对TLS1.2的支持是双重的。如果您真的想支持API 21下的任何内容,那么将您的OkHttp版本更新到3.12.x,直到2020年12月31日为止。

票数 1
EN

Stack Overflow用户

发布于 2019-03-20 13:07:06

终于!!我解决了这个问题。解决之道是使用阻断器。通过检查正确的SDK版本和拦截器,我终于开始运行我的程序了。

代码语言:javascript
复制
internal class HeaderInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {    
var request = chain.request()    
val url = request.url().newBuilder()
            .addQueryParameter("key", API_KEY)
            .addQueryParameter("q", QUERY_PARAMETER)
            .addQueryParameter("days", DAYS)
            .build()
request = request.newBuilder().url(url).build()
return chain.proceed(request)
  }
}

OkHttpClient需要SDK_VERSION检查-

代码语言:javascript
复制
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
   builder.addInterceptor(HeaderInterceptor())
}

因此,这里对我来说是-@QueryMap(在改造中)很好地构建了SDK-21+的url。对于SDKs<21,我使用了如上所述的拦截器来构建url。

我感谢大家在这件事上给予的帮助。我相信外面的人会发现这很有帮助的!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55256964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档