2015-11-06 72 views
0

我需要使用Volley請求將一些數據從遠程服務器返回到我的應用程序,但經過一段時間測試後,我無法使其工作。方法返回值但未正確傳遞值

我有一個看起來像這樣的代碼:

String recipientUsername = foo; 
picture = retrievedPicture(recipientUsername); 
Log.i(TAG, "String picture: " + picture); 
recipientPicture = (NetworkImageView) findViewById(R.id.chat_image_circle_pic); 
recipientPicture.setImageUrl(picture, imageLoader); 

所以picture全局聲明來檢索與排球內的方法的價值。在我的日誌時,上面的紋路讀這個樣子的:

I/ChatActivity: String picture: null 

它得到令人困惑的方法本身實際上是返回的東西。該方法是這樣的:

public String retrievedPicture(final String username) { 
    // Tag used to cancel request 
    String tag_string_req = "req_update_user"; 

    StringRequest stringRequest = new StringRequest(Request.Method.POST, 
      AppConfig.URL_RETRIEVE, new Response.Listener<String>() { 
     @Override 
     public void onResponse(String response) { 
      Log.d(TAG, "User is retrieving on MySQL: " + response.toString()); 

      try { 
       JSONObject jObj = new JSONObject(response); 
       boolean error = jObj.getBoolean("error"); 
       if (!error) { 
        // Do no changes on SQLite at the moment 
        JSONObject userObj = jObj.getJSONObject("user"); 
        picture = userObj.getString("picture"); 
        Log.d(TAG, "Picture retrieved from MySQL: " + picture); 
       } else { 
        // Error occurred in updating user's data. Get the error message from php node: 
        String errorMsg = jObj.getString("error_msg"); 
        Log.e(TAG, errorMsg); 
        //Toast.makeText(getActivity(), errorMsg, Toast.LENGTH_SHORT).show(); 
       } 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
     } 
    }, new Response.ErrorListener() { 
     @Override 
     public void onErrorResponse(VolleyError error) { 
      Log.e(TAG, "Error in retrieving user's data: " + error); 
     } 
    }) { 
     @Override 
     protected Map<String, String> getParams() { 
      // Posting the params to php (nodes, data to be changed) 
      Map<String, String> params = new HashMap<>(); 
      params.put("tag", "retrievepic"); 
      params.put("username", username); 
      return params; 
     } 
    }; 

    // Adding request to the request queue 
    AppController.getInstance().addToRequestQueue(stringRequest, tag_string_req); 

    return picture; 
} 

和日誌表明,該方法不工作:

D/ChatActivity: User is retrieving on MySQL: {"tag":"retrievepic","error":false,"uid":19,"user":{"username":"test07","picture":"http:\/\/192.168.0.3\/worka\/uploads\/test07_05112015_155304.jpg"}} 
D/ChatActivity: Picture retrieved from MySQL: http://192.168.0.3/worka/uploads/test07_05112015_155304.jpg 

所以我可以猜測的是,我不是從法的try catch塊遞東西。如果是這樣,我能做些什麼來正確傳遞值? try catch塊已經嵌套在一個似乎固定的void方法中。我真的希望有這樣的解決方案,所以我可以把這個方法變成一個實用程序類。感謝閱讀傢伙!

+1

請在下面閱讀我的答案http://stackoverflow.com/questions/33535435/how-to-create-a-proper-volley-listener-for-cross-class-volley-method-calling/33535554# 33535554 – BNK

回答

1

您的問題是picture由於您的方法而導致返回時始終爲空。

排出請求是異步的 - 它們在工作線程上執行並在將來返回結果。您會收到onResponse()的結果。這就是爲什麼你在你的logcat中看到正確的東西。

作爲該方法的結果,返回picture時,請求尚未執行,並且picture的值爲null

作爲一種解決方案,您應該更改方法的返回類型,將請求執行到void並將圖像加載邏輯移動到onResponse()

+0

感謝您的迴應,因爲這清除了很多,特別是異步任務。我最初將它放在'onReponse()'中,但我想將它變成一個實用程序類,我可以毫不費力地繼續使用代碼。那可能嗎? –

+1

當然。我建議你分開用於發出請求和解析響應的實際代碼。它可以爲您提供一種控制器或API客戶端。您可以公開一個看起來像'retrieveImage(Listener listener)'的方法,其中'Listener'是一個帶有兩個方法的回調接口 - onImageLoaded(String imagePath)'和'onError()'。在片段/活動中,您調用'retrieveImage(Listener)'方法並提供一個回調實現,您可以在ImageView上設置圖像URL。 –

+0

謝謝@ danail-alexiev,這很有幫助!對這個專長使用'Listener'對我來說是比較新的,但我正在慢慢地獲得這張照片。有沒有鏈接或一些關鍵字,我可以找到更多的指針實現這個? –

1

所以我可以猜到的是我沒有通過任何方法的嘗試 catch塊。

您正在返回當前值picture。你正在做錯誤的假設,UI線程正在等待

AppController.getInstance().addToRequestQueue 

要完成。事實並非如此。

1

retrievedPicture()方法將返回圖片的默認值很明顯,因爲volley will execute request asynchronously

在行AppController.getInstance().addToRequestQueue(stringRequest, tag_string_req);。你是executing volley request這是asynchronous,所以我n very next line you are returning picture, yet volley response is not received。這就是爲什麼你的方法返回default value

您應該執行recipientPicture.setImageUrl(picture, imageLoader);裏面的onResponse()方法,其中凌空響應收到。

1

pictureonResponse之前返回。

嘗試使用EventBus

使用EventBus發佈Event

比你可以得到的事件,並繼續。