2014-05-05 60 views
1

我是一名初學者的android開發者,現在我正面臨使用google volley進行http調用的大問題。我做了我自己的庫來處理所有REST API請求,並且我必須將響應返回給ACTIVITY,但是調用是異步的,並且在我調用返回的時候沒有到達。這是LIB:Android排球:自己的REST庫

public class RestServices implements IRestServices { 
Object responseFromServer = null; 
public Object getJsonResponseObjectByAttributes(String... attributes) { 
     RequestQueue queue = VolleyProvider.getQueue(ConnectionConstants.context); 
     String finalUri = makeRequestUri(attributes); 
     JsonObjectRequest jsonRequest = new JsonObjectRequest(
       Request.Method.GET, finalUri, null, new Response.Listener<JSONObject>() { 

        public void onResponse(JSONObject response) { 


        } 
       }, new Response.ErrorListener() { 

        public void onErrorResponse(VolleyError error) { 
         // TODO Auto-generated method stub 

        } 
       }); 

     jsonRequest.setTag(ConnectionConstants.TAG); 
     queue.add(jsonRequest); 

return responseFromServer; 
} 

而這裏就是我所說的服務:

public class MainViewModel implements IMainViewModel { 

    @Inject IRestServices restServices; 

    // Define our server URL 
    public static final String SERVER_URL = "API_Url"; 

    public String getServerResponse() { 
     Object jsonResponse = restServices.getJsonArrayResponseObjectByAttributes(""); 
     User user = (User) jsonResponse; 
     return user.toString(); 
    } 

    public void InitializeViewModel(Context context) { 
     restServices.InitializeService(SERVER_URL, context);  
    } 

} 

我還使用Roboguice政府間海洋學委員會。提前致謝。

回答

0

您需要將結果分配給您的變量和執行等待,直到接收到的結果:

public class RestServices implements IRestServices { 
    private Object responseFromServer = null; 

    public void getJsonResponseObjectByAttributes(String... attributes) { 
     RequestQueue queue = VolleyProvider.getQueue(ConnectionConstants.context); 
     String finalUri = makeRequestUri(attributes); 
     JsonObjectRequest jsonRequest = new JsonObjectRequest(
      Request.Method.GET, finalUri, null, new Response.Listener<JSONObject>() { 
       public void onResponse(JSONObject response) { 
        //add this line to update the result 
        responseFromServer = response; 
       } 
      }, new Response.ErrorListener() { 
       public void onErrorResponse(VolleyError error) { 
        // TODO implement Error handling 
       } 
      }); 

     jsonRequest.setTag(ConnectionConstants.TAG); 
     queue.add(jsonRequest); 
    } 
    //added getter for result 
    public Object getResponseFromServer(){ 
     return responseFromServer; 
    } 
} 

這是一個繁忙的等待(因爲它比較容易表現出它應該如何工作)和消耗大量的CPU使用量。您應該用阻塞等待來替換它(請參閱線程方法wait,notify和yield以及像信號量一樣鎖定)。

public String getServerResponse() { 
    restServices.getJsonArrayResponseObjectByAttributes(""); 
    while(restServices.getResponseFromServer() == null){ 
     //busy waiting to get sure the result is != null after this loop; 
     Thread.sleep(10);//add catch 
    } 
    Object jsonResponse = restServices.getResponseFromServer(); 
    User user = (User) jsonResponse; 
    return user.toString(); 
} 
+0

謝謝,但我正在尋找使lib可以從調用方完全隔離,目的是重用它。那麼有沒有什麼辦法在lib中執行等待? – Ultegra

+0

是的,在調用'getJsonArrayResponseObjectByAttributes'的'restServices'中添加一個新方法,並在返回結果之前實現等待。 – Simulant

+0

我要試一試。我會更新我的結果。謝謝。 – Ultegra

0

如果我理解正確,您嘗試在撥打電話後不會從您的方法返回,而是在結果存在之後。下面你會找到一個如何做到這一點的例子,這個例子的關鍵是使用未來,然後做一個future.get(),直到有來自web服務的響應,這個代碼纔會繼續執行。

//fill params 
JSONObject params = new JSONObject(); 
params.put("username", username); 
params.put("password", password); 

//create future request object 
RequestFuture<JSONObject> future = RequestFuture.newFuture(); 
//create JsonObjectRequest 
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST, URL, params, future, future); 
//add request to volley 
MyVolley.getRequestQueue().add(jsObjRequest); 
try { 
      JSONObject response = future.get();// this is where the process will 
               //wait until a result comes back 
      } catch (Exception e) { 
      e.printStackTrace(); 
    } 
    return response; 
+0

我試過你的解決方案,但是當future.get()啓動時,應用程序被阻止,響應永遠不會到達。看起來這條線被稱爲主線程被阻塞。謝謝! – Ultegra

+0

future.get()不會阻止網絡請求發生。一般而言,期貨可以讓你從一個方法異步返回一個對象,但是當你完成之後,你仍然繼續工作,並把結果放到未來的對象中。這在後端開發中是一種相當普遍的做法,並且已經開始在android中變得更加流行。是的,主線程會被future.get()阻塞,但是volley會在不同的線程上執行其所有網絡通信,並將結果放到未來。 – FriendlyMikhail