我正在面對一個關於如何返回異步連接的值的問題。異步連接的返回值
我想要做的就是創建一個函數(如「getById」)的詢問一臺服務器,並返回包含服務器的答案的對象。
我試着用很多不同的HTTP客戶端,但我得到的是剛剛創建的局部變量/與UI交互,而不是返回值的可能性。
在幾乎所有的HTTP客戶端使用的主要架構是:創建一個請求,並請求處理程序處理它,並傳遞給它的響應處理,將處理響應。
什麼情況是,我無法訪問來自請求處理程序的響應,並沒有檢測時的要求,以與響應交互已經完成;另一方面,從響應處理程序中,我可以使用響應來進行UI更改或將其存儲在本地,但我無法將其作爲函數結果返回給用戶。
有什麼辦法可以避免這種行爲,或繞過/破解它?
我想主要是4種方式:
- 利用期貨& FutureTasks。問題:我只能在請求處理程序上調用它們,所以我無法檢測到響應已準備好,而只是在請求處理程序準備就緒時。
- 使用回調。問題:與期貨和未來任務相同。
- 使用一段時間(true),檢查響應是否準備就緒。雖然這在理論上可能會起作用,但實際上它會在主線程上產生阻塞,所以應用程序會凍結,並且會永久停留在while(true)上,因爲它無法執行可以解鎖它的代碼。
- 使用多線程。這可以防止阻塞主線程,但問題是線程無法返回值,並且響應處理程序無法訪問在另一個線程上使用的鎖(或者看起來像這樣),所以我無法通知後臺任務完成。
有沒有我沒有考慮過的方法,或者我可能沒有正確實施的任何方法?
一些示例代碼;在這段代碼中我使用的循環J的Android系統的異步HTTP客戶端,可here:
public JSONObject getById(String url, String id) {
JSONObject jo = null;
AsyncHttpClient client = new AsyncHttpClient();
final AsyncHttpResponseHandler ahrh = new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
try {
jo = new JSONObject(new String(responseBody, "UTF-8"));
} catch (JSONException | UnsupportedEncodingException e) {
}
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
}
};
client.get(url + id, ahrh);
return jo;
}
,因爲值纔可以返回這個例子失敗。
你擁有了它已經,其所謂的AsyncTask類,它處理所有。 – Nanoc
http://developer.android.com/reference/android/os/AsyncTask.html – Fildor
你會如何使用AsyncTask來改善代碼? 在我看來,如果你把它包含在一個AsyncTask中,你將面臨同樣的問題,但是在這個類中,因爲你仍然需要一種溝通方式來表示響應已經準備好了 – tenik