發現:
在接微信登錄時,通過構造 OkHttpClient 對象發起一次請求並加入隊列,待服務端響應後,回調 Callback 接口觸發 onResponse() 方法,然後在該方法中通過 Response 對象處理返回結果、實現業務邏輯。
大致代碼如下:
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()只允許調用一次
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() 中,爲便於調試,我打印了返回體,然後通過 parseResponseStr() 方法解析返回體(注意:這兒兩次調用了 response.body().string())。
這段看起來沒有任何問題的代碼,實際運行後卻出了問題,,通過debug發現result在轉換成jsonObject時爲null。
那爲什麼result會變爲null呢?通過網上資料查閱發現,response.body().string()只能調用一次,調用完就會釋放掉資源,恍然大悟。。。然後我點進源碼看了一下:
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);
很棒,原來在我們調用了response.body的String()方法之後OkHttp 將響應體的緩衝資源返回的同時,調用 closeQuietly() 方法默默釋放了資源。就是這個原因了。Get√
參考:OkHttp踩坑記:爲何 response.body().string() 只能調用一次?
多問多看吧!