欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關于OkHttp中response.body().string()的用法解析

 更新時間:2023年06月17日 14:28:05   作者:Songbl_  
這篇文章主要介紹了關于OkHttp中response.body().string()的用法解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

OkHttp中response.body().string()解析

在多次引用response.body().string()的時候,程序會崩潰掉。

下面通過源碼分析:

ResponseBody body = response.body();//獲取響應體

Response中的string()方法如下:

? public final String string() throws IOException {
? //通過使用指定的 charset 解碼指定的 byte 數(shù)組,構(gòu)造一個新的 String
? ? return new String(bytes(), charset().name());
? }

對于bytes()方法

public final byte[] bytes() throws IOException {
? ? long contentLength = contentLength();
? ? if (contentLength > Integer.MAX_VALUE) {
? ? ? throw new IOException("Cannot buffer entire body for content length: " + contentLength);
? ? }
? ? BufferedSource source = source();
? ? byte[] bytes;
? ? try {
? ? ? bytes = source.readByteArray();
? ? } finally {
? ? ? Util.closeQuietly(source);
? ? }
? ? if (contentLength != -1 && contentLength != bytes.length) {
? ? ? throw new IOException("Content-Length and stream length disagree");
? ? }
? ? return bytes;
? }

可以看到,在finally中,執(zhí)行了資源的關閉操作。

在拿到資源之后,就將資源關閉了,所以只能獲取一次實體。

對于charset()方法

private Charset charset() {
?MediaType contentType = contentType();
?return contentType != null ? contentType.charset(UTF_8) : UTF_8;
? }
public static final Charset UTF_8 = Charset.forName("UTF-8");

根據(jù)響應頭中的contentType 決定編碼形式。轉(zhuǎn)換為UTF-8.

OkHttp的坑:response.body().string() 只能調(diào)用一次

發(fā)現(xiàn)

在接微信登錄時,通過構(gòu)造 OkHttpClient 對象發(fā)起一次請求并加入隊列,待服務端響應后,回調(diào) Callback 接口觸發(fā) onResponse() 方法,然后在該方法中通過 Response 對象處理返回結(jié)果、實現(xiàn)業(yè)務邏輯。

大致代碼如下

? private void getUserInfo() {
? ? ? ? String path = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openid;
? ? ? ? OkHttpClient client = new OkHttpClient();
? ? ? ? Request request = new Request.Builder()
? ? ? ? ? ? ? ? .url(path)
? ? ? ? ? ? ? ? .build();
? ? ? ? Call call = client.newCall(request);
? ? ? ? call.enqueue(new Callback() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onFailure(Call call, IOException e) {
? ? ? ? ? ? ? ? Log.d(TAG, "onFailure: userinfo" + e.getMessage());
? ? ? ? ? ? ? ? finish();
? ? ? ? ? ? }
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onResponse(Call call, Response response) throws IOException {
// ? ? ? ? ? ? ? ?Log.d(TAG, "onResponse: userinfo" + response.body().string()); ? ?//okhttp中 response.body().string()只允許調(diào)用一次
? ? ? ? ? ? ? ? final String result = response.body().string();
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? JSONObject jsonObject = new JSONObject(result);
? ? ? ? ? ? ? ? ? ? unionId = jsonObject.getString("unionid");
? ? ? ? ? ? ? ? ? ? headImgUrl = jsonObject.getString("headimgurl");
? ? ? ? ? ? ? ? ? ? nickname = jsonObject.getString("nickname");
? ? ? ? ? ? ? ? ? ? Log.d(TAG,"getUserInfo: unionId = "+unionId+" ?headImgUrl = "+ headImgUrl + " ?nickname = "+ nickname);
? ? ? ? ? ? ? ? } catch (JSONException e) {
? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? finish();
? ? ? ? ? ? }
? ? ? ? });
? ? }

在 onResponse() 中,為便于調(diào)試,我打印了返回體,然后通過 parseResponseStr() 方法解析返回體(注意:這兒兩次調(diào)用了 response.body().string())。

這段看起來沒有任何問題的代碼,實際運行后卻出了問題,,通過debug發(fā)現(xiàn)result在轉(zhuǎn)換成jsonObject時為null。

那為什么result會變?yōu)閚ull呢?通過網(wǎng)上資料查閱發(fā)現(xiàn),response.body().string()只能調(diào)用一次,調(diào)用完就會釋放掉資源,恍然大悟。。。

然后我點進源碼看了一下:

public final String string() throws IOException {
? ? BufferedSource source = source();
? ? try {
? ? ? Charset charset = Util.bomAwareCharset(source, charset());
? ? ? return source.readString(charset);
? ? } finally {
? ? ? Util.closeQuietly(source);
? ? }
? }
Util.closeQuietly(source);

很棒,原來在我們調(diào)用了response.body的String()方法之后OkHttp 將響應體的緩沖資源返回的同時,調(diào)用 closeQuietly() 方法默默釋放了資源。

就是這個原因了。Get√

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

最新評論