[okhttp] ResponseBody class

SC Tuan
3 min readDec 19, 2022

--

本文是參考官方文件的粗略翻譯。

由伺服器到用戶端的一次性的數據流(Stream),帶著 response body 的 raw bytes。

使用響應主體的原始位元組從源伺服器到客戶端應用程式的一次性流。 與Web伺服器的主動連線支援每個 response body。 這施加了義務和限制於client application。

必須關閉 Response body

每個 response body 皆由有限的資源(socket 或檔案)所支援,漏關閉的 response body 可能會導致資源洩漏獲釋應用程式變慢或閃退。

ResponseBodyResponse 類別都實作了 Closeable 。關閉 reponse 就是關閉他的 repsonse body。如果你呼叫了 Call.execute() 或是實做了 Callback.onResponse(okhttp3.Call, okhttp3.Response) ,你就必須關閉這個 body ,可以呼叫下列的方法來關閉。

  • Response.close()
  • Response.body().close()
  • Response.body().source().close()
  • Response.body().charStream().close()
  • Response.body().byteStream().close()
  • Response.body().bytes()
  • Response.body().string()

對同樣的 response body 呼叫多次 close() 沒有益處。

對於同步呼叫 (synchronous calls),確保關閉 response body 最簡單的做法是用 try 區塊。編譯器會插入隱式的 finally 來呼叫 close()

Call call = client.newCall(request);
try (Response response = call.execute()) {
... // Use the response.
}

非同步呼叫的話如下:

Call call = client.newCall(request);
call.enqueue(new Callback() {
public void onResponse(Call call, Response response) throws IOException {
try (ResponseBody responseBody = response.body()) {
... // Use the response.
}
}

public void onFailure(Call call, IOException e) {
... // Handle the failure.
}
});

如果你有在其他 thread 使用 response body,這些範例將會失效。若此,要在那些有讀取 response body 的 thread 裡面呼叫 close()

response body 只能使用一次

這個類別可能會用於非常大量的 reponse。舉例來說,透過此類別去讀取一個使用了極大量記憶體的 reponse 。像是影片的串流應用程式。

由於該類別不會緩衝完整的 response 到記憶體中,因此應用程式可能不會重讀響應的位元組。若要將整個 reponse 讀入記憶體,可用 bytes()string()。 或者使用 source()byteStream()charStream()

--

--

SC Tuan
SC Tuan

Written by SC Tuan

iOS developer(Obj-C & Swift) / Web developer (Java, Javascript, CSS,HTML)

No responses yet