Android okhttp3中的坑

本文详细解析了在使用OkHttp3.14.0版本时遇到的BootstrapMethodError异常,指出问题源于旧版教程中对okio的不必要依赖,并提供了正确的依赖包配置方案。

因为自己的毕设需要用到用户数据交互,所以想学一个Android 的网络请求框架。

在网上一搜结果发现Okhttp + retrofit + rxjava特别火,所以就学习一下,顺便再网上搜了源码以备学习之用,结果遇到一个大坑。

错误说明如下:

2019-04-10 12:00:05.903 19895-19895/com.main.mytest_okhttp2 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.main.mytest_okhttp2, PID: 19895
java.lang.BootstrapMethodError: Exception from call site #4 bootstrap method
at okhttp3.internal.Util.(Util.java:87)
at okhttp3.internal.Util.immutableList(Util.java:234)
at okhttp3.OkHttpClient.(OkHttpClient.java:124)
at com.main.mytest_okhttp2.MainActivity.(MainActivity.java:14)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
at android.support.v4.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:43)
at android.app.Instrumentation.newActivity(Instrumentation.java:1215)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2831)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at …
我就写了一行代码。。。

OkhttpClient client = new OkhttpClient();

完全按照源码上的教程写的,以及依赖包导入,然后在网上找了很久都没得解答,有说jdk8新特性的问题,但是我这个情况不是的,那么原因出在哪呢,经过多方求助,现将解决方案公布如下:

网上关于这个网络请求框架,所用的okhttp依赖包的版本是低版本,根据教程的要求,除了要导入okhttp以外,还需要导入okio,因此错误就是在这里。我所使用的okhttp版本是3.14.0,在这个最新的版本下面,已经不需要导入okio,如果导入了,就会报上面的错误,因此你只需要导入okhttp3.14.0版本的依赖包即可

另外,如果此方法还不能解决,建议不要使用android studio自动搜索使用的okhttp的jar包,去优快云找能够使用的okhttp和okio的jar包。

好啦,问题解决了。祝大家工作生活愉快!!!

<think>嗯,用户现在想了解如何使用OkHttp3发送带参数的GET请求。用户提供了站内引用,展示了基本GET请求的实现,但没有直接提供带参数的示例。用户可能是个Android开发者,正在调试网络请求功能。从查询的精确性来看,用户应该有一定OkHttp基础,但需要具体的参数传递示例。这种需求在实际开发中很常见,比如需要调用带查询字符串的API。在准备回答时,需要考虑三个技术要点:第一是参数构造的正确方法。虽然可以直接拼接URL字符串,但官方推荐使用HttpUrl.Builder更安全,能自动处理特殊字符编码问题。第二要区分同步和异步调用的差异。之前的引用[1]和[3]已经展示了这两种模式的基本用法,只需在此基础上增加参数部分即可。第三要特别注意线程安全问题。在回调中处理响应时,需要提醒用户注意Android的线程限制,比如不能直接更新UI。考虑到用户可能遇到的点,应该在示例中特别说明两个易错点:一是中文参数必须编码,否则会乱码;二是如果参数值包含特殊字符(如&符号),手动拼接容易出错。这正是推荐使用Builder的核心原因。用户之前查过资料但没找到具体方案,所以采用最直观的分步示例会更友好。准备分别演示同步请求和异步请求两种场景,并强调关键步骤的注意事项。另外注意到引用[4]提到响应计数的方法,虽然与当前问题无关,但可能暗示用户之后会需要处理重定向等高级特性。不过这已经超出本次问题范围了。</think> 要在OkHttp3中实现带参数的GET请求,核心是正确构造包含查询参数的URL。以下是具体实现方法及示例: ### 1. 使用 `HttpUrl.Builder` 构建带参URL(推荐) ```java OkHttpClient client = new OkHttpClient(); // 1. 构造带参数的URL HttpUrl url = new HttpUrl.Builder() .scheme("https") // 协议 .host("api.example.com") // 主机地址 .addPathSegment("data") // 路径 .addQueryParameter("key1", "value1") // 参数1 .addQueryParameter("key2", "中文") // 中文参数自动编码 .addQueryParameter("page", "1") // 参数2 .build(); // 2. 创建请求 Request request = new Request.Builder() .url(url) .get() // 显式声明GET(可省略) .build(); // 3. 同步执行请求 try (Response response = client.newCall(request).execute()) { if (response.isSuccessful()) { System.out.println(response.body().string()); } } catch (IOException e) { e.printStackTrace(); } ``` > **自动编码说明**: > `addQueryParameter()` 会自动对特殊字符和中文进行URL编码,避免手动处理 `URLEncoder.encode()`[^2] ### 2. 手动拼接URL(简易场景) ```java String baseUrl = "https://api.example.com/data?"; String fullUrl = baseUrl + "key1=" + URLEncoder.encode("value1", StandardCharsets.UTF_8.name()) + "&key2=" + URLEncoder.encode("中文", StandardCharsets.UTF_8.name()); Request request = new Request.Builder() .url(fullUrl) .build(); // 后续执行步骤同上 ``` > **注意**:手动拼接时必须使用 `URLEncoder.encode()` 处理特殊字符,否则参数值含空格/中文时会报错[^2] ### 异步请求示例 ```java client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { e.printStackTrace(); } @Override public void onResponse(Call call, Response response) throws IOException { try (ResponseBody body = response.body()) { if (response.isSuccessful()) { System.out.println(body.string()); } else { System.out.println("请求失败: " + response.code()); } } } }); ``` ### 关键点总结 1. **参数安全** - 优先使用 `HttpUrl.Builder` 避免编码错误 - 手动拼接时 **必须** 用 `URLEncoder.encode()` - 空格需转为 `+` 或 `%20`(自动处理) 2. **符号处理** 保留字符如 `&`, `=` 在参数值中出现时会被自动编码为 `%26`, `%3D` 等[^3] 3. **特殊场景** ```java .addQueryParameter("ids", "101,102,103") // 数组参数:逗号分隔 .addQueryParameter("sort", "-date") // 排序参数 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值