方法返回了一个值,但该值未正确传递

Method returned a value but the value not passed correctly

我需要使用 Volley 请求 return 从远程服务器向我的应用发送一些数据,但经过一段时间的测试后我无法让它工作。

我的代码如下所示:

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 被全局声明以从内部有 Volley 的方法中检索值。在我的日志中,当读取以上行时,它看起来像这样:

I/ChatActivity: String picture: null

当方法本身实际上是 return 时,这会变得更加混乱。该方法如下所示:

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 方法中。我真的希望有一个解决方案,这样我也可以将该方法变成一个实用程序 class。感谢大家阅读!

So what I could guess is that I'm not passing anything from the try catch block of the method.

您正在返回 picture 的当前值。您错误地假设 UI 线程正在等待

AppController.getInstance().addToRequestQueue

完成。那不是真的。

你的问题是 picture 当你 return 它作为你的方法的结果时总是空的。

Volley 请求是异步的 - 它们在工作线程上执行,并且 return 在将来的某个时间得到结果。系统会通知您结果在 onResponse() 中。这就是为什么您在 logcat.

中看到正确的内容

当时你returnpicture作为方法的结果,请求还没有被执行,picture的值为null

作为解决方案,您应该更改方法的 return 类型,将请求执行到 void 并将图像加载逻辑移动到 onResponse().

retrievedPicture()方法将return图片的默认值显而易见,因为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。这就是为什么你的方法是 returning default value.

您应该在 onResponse() 方法中执行 recipientPicture.setImageUrl(picture, imageLoader);,其中接收到 volley 响应。

picturereturn前onResponse.

尝试使用EventBus.

使用EventBuspost一个Event.

然后你可以得到事件并继续。