[英]Multiple asynchronous request handling in java
我正在寫android應用程序,它使用一些站點api。 該站點提供了一些用於處理此api的SDK。 我正在用它向網站提出一些要求。
因此,要發出請求,我應該這樣做:
VKRequestListener listener = new VKRequestListener(){
@Override
public void onComplete(VKResponse response){
// do smth when response is complete
}
}
VKRequest vkRequest = new VKRequest("request", "parameters");
vkRequest.executeWithListener(listener);
該listener
異步運行,因此,如果我發出單個請求,一切都會很好:我可以在onComplete
方法中處理它。 但是,如果我需要發出多個請求,而且每個下一個請求都取決於先前的響應,該怎么辦? 我只看到兩種方法,兩種方法看起來都很糟糕:
1. 使用onComplete
方法發出每個下一個請求。 這似乎過於嵌套和不靈活。
2.進行 某種同步操作:在主線程執行請求之后,以某種方式檢查onComplete
執行(btw,如何?使用某種標志對象?),否則,執行Thread.sleep(1000)
,重復此操作直到返回響應,而不是做出其他回應。
因此,請告訴我是否有“正常”方式來處理多個異步請求?
Java中的Multiple Async確實很難看,太多樣板了。 以下是如何手動滾動所需內容的方法。 但我建議也研究圖書館。
如果很好地分解了代碼,這里就沒有嵌套(至少不是很明顯):如果已經有了必要的數據,甚至可以在鏈的中間開始。 基本上,您可以基於VK類創建自己的異步接口,但VK完全隱藏。
class MyRequests {
interface GetStuffResult {
void done(String result, float result2);
// you can even put other callbacks here to help make decisions in the chain
// based on UI element states for example
}
static void startGetStuff1(String param1, String param2, final GetStuffResult result) {
VKRequestListener listener = new VKRequestListener(){
@Override
public void onComplete(VKResponse response){
// extract parameters for next request
String newParameter1 = ...;
int newParameter2 = ...;
startGetStuff2(newParameter1, newParameter2, result);
}
};
VKRequest vkRequest = new VKRequest("request", buildParameters1(param1, param2));
vkRequest.executeWithListener(listener);
}
static void startGetStuff2(String param1, int param2, final GetStuffResult result) {
VKRequestListener listener = new VKRequestListener(){
@Override
public void onComplete(VKResponse response){
// extract parameters for next request
startGetStuff3(newParameter1, newParameter2, newParameter3, result);
}
};
VKRequest vkRequest = new VKRequest("request", buildParameters2(param1, param2));
vkRequest.executeWithListener(listener);
}
static void startGetStuff3(String param1, int param2, Date param3, final GetStuffResult result) {
VKRequestListener listener = new VKRequestListener() {
@Override
public void onComplete(VKResponse response) {
// extract result
result.done(resultingString, resultingFloat);
}
};
VKRequest vkRequest = new VKRequest("request", buildParameters3(param1, param2, param3));
vkRequest.executeWithListener(listener);
}
}
要使異步請求同步,您可以執行以下操作:
只能在后台線程上執行此操作! 還要注意, AsyncTask
按1的AsyncTask
執行任務,因此,如果將其放在AsyncTask
它將阻止其他異步任務執行!
final AtomicReference<VKResponse> result = new AtomicReference<>();
final CountDownLatch latch = new CountDownLatch(1);
VKRequestListener listener = new VKRequestListener(){
@Override
public void onComplete(VKResponse response){
result.set(response);
latch.countDown();
}
};
VKRequest vkRequest = new VKRequest("request", "parameters");
vkRequest.executeWithListener(listener);
// call countDown() even if the request fails if you have an error callback as well!
// and check the existence of response/flag you set if it failed
try {
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
VKResponse response = result.get(); // will be null if interrupted
// do smth when response is complete
見這對中斷!
您應該嘗試使用Java中的反應性擴展RxJava實現。 它允許通過可觀察對象以非常簡單的方式來組成異步調用。 還有一個android擴展RxAndroid ,可讓您訪問android調度程序以及活動或片段生命周期感知的可觀察對象。
關於在Android上使用Rx的教程和文章很少,但是您應該簽出Dan Lew的教程和文章,因為它涵蓋了您需要的所有東西。 鏈接在這里: Grokking RxJava
我很多時候都在考慮簡單的解決方案,而我做到了:
class RequestFlags{
int requestCount;
Params params;
};
private final RequestFlags requestFlags;
public requestWrapper(RequestFlags rf){
VKRequestListener listener = new VKRequestListener(){
@Override
public void onComplete(VKResponse response){
// do smth when response is complete
if(requestFlags.requestCount != 0) {
requestFlags.requestCount--;
requestFlags.params = doSmth(response);
requestWrapper(requestFlags);
} else{
// we finished - do smth on finish
}
}
}
Params someParams;
switch(requestFlags.params){
case param1: someParams = doSmthElse();
break;
case param2: someParams = null;
break;
// etc, etc...
}
VKRequest vkRequest = new VKRequest("request", someParams);
vkRequest.executeWithListener(listener);
}
因此,此請求包裝程序將以遞歸方式調用自身,直到所有請求均連貫且謹慎地處理為止。希望這對某些人有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.