如何从Volley的onResponse函数返回值?

62
public class getString  {
String tag_string_req = "string_raq";
String url = "http://10.0.2.2/eat/locations/index.json";
String result="";

public String get_String() {
    StringRequest strReq = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            result=response;
            System.out.println(response);
            ;

        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError volleyError) {
            System.out.println(volleyError.getMessage());
        }
    });
    AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
    return result;
}}

我希望构建一个getString对象并在其他字段中调用get_String。但是从onResponse中获取结果似乎很困难。我知道目前这种方式不起作用。有人能帮我解决这个问题吗?

3个回答

154
您希望使用回调接口,如下所示:
public void getString(final VolleyCallback callback) {
    StringRequest strReq = new StringRequest(Request.Method.GET, url, new     Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            ...  // (optionally) some manipulation of the response 
            callback.onSuccess(response);
        }
    }...
}}

回调函数的定义如下:

public interface VolleyCallback{
    void onSuccess(String result);
}

活动内的示例代码:

public void onResume(){
    super.onResume();

    getString(new VolleyCallback(){
         @Override
         public void onSuccess(String result){
             ... //do stuff here
         }
    });
}

如果您想要进行处理,可以使用泛型使VolleyCallback更加健壮,或者添加start()failed(Exception e)complete()等方法来进行更细粒度的状态检查。

请记住,这是异步调用,因此当您在success()中收到结果时,您将不得不更新视图等操作。


2
@morha13 只需在方法签名中将回调变量声明为 final,因为您不会更改它(至少在这种基本情况下):public void getString(final VolleyCallback callback)。我已经修改了答案以反映这一点。 - wblaschko
1
有人能给我一个Volley回调的示例吗? - Raunak Pandey

0
正如wblaschko提出的非常好的解决方案所述,我理解这个解决方案可能对那些经验稍微少一点的人来说有点困惑。下面是我编辑过的解决方案,建立在wblaschko的解决方案之上:
VolleyCallback.java(接口)
public interface VolleyCallback {
    void onSuccess(String result);
    void onError(String result);
}

我创建了一个HTTPRequest类来保持代码整洁。
HTTPReq.java(类)
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;

public class HTTPReq {
    public static StringRequest getRequest(String path, final VolleyCallback callback) {
        // Instantiate the RequestQueue.
        String url = "https:// **FILL HERE BASE API URL** /" + path;

        // Request a string response from the provided URL.
        StringRequest stringRequest = new StringRequest(Request.Method.GET, URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        // Display the first 500 characters of the response string.
                        callback.onSuccess(response);
                    }
                }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                callback.onError(error.toString());
            }
        });

        return stringRequest;
    }
}

最后,在活动中,您需要实现以下代码:
创建一个全局变量:
private RequestQueue mQueue;

接下来,在一个活动的onCreate函数中应用VolleyRequestQue:

mQueue = Volley.newRequestQueue(this);

最后,这个函数实际上执行API请求并可以捕获响应:
mQueue.add(HTTPReq.getRequest( **FILL WITH PATH AND/OR PARAMS**, new VolleyCallback() {
    @Override
    public void onSuccess(String result) {
        System.out.println(result);
    }

    @Override
    public void onError(String result) {
        System.out.println(result);
    }
}));

希望这样更清晰明了。


0
override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {


    val rootView = inflater.inflate(R.layout.mission_fragment_list, container, false)
    val recycler = rootView.findViewById(R.id.list) as RecyclerView

    GlobalScope.async {
        val queue = Volley.newRequestQueue(context)
        val gson = Gson()

        val url = "YPUR_API"
        val stringRequest = StringRequest(
            Request.Method.GET, url,
            Response.Listener<String> { response ->

                recycler.layoutManager = LinearLayoutManager(context)
                val listType: Type = object : TypeToken<MutableList<MissionModel>?>() {}.type
                val data: MutableList<MissionModel> = gson.fromJson(response, listType)
                recycler.adapter = MissionAdapter(data)
            },
            Response.ErrorListener { error ->
                error.printStackTrace()
            })

        queue.add(stringRequest)


    }
    return rootView

}

简单的代码。您需要添加依赖项 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接