Android Volley - 如何在另一个类中隔离请求

时间:2015-01-27 14:10:27

标签: android android-volley

您好我想模拟排球请求,因此我不会将活动演示代码与排球请求混在一起。 我看到的所有样本,排序请求都是例如 - 来自活动按钮的OnClick事件。

我的意思是这段代码(取自差异来源):

// prepare the Request
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, url, null,
    new Response.Listener<JSONObject>() 
    {
        @Override
        public void onResponse(JSONObject response) {   
                        // display response     
            Log.d("Response", response.toString());
        }
    }, 
    new Response.ErrorListener() 
    {
         @Override
         public void onErrorResponse(VolleyError error) {            
            Log.d("Error.Response", response);
       }
    }
);

// add it to the RequestQueue   
queue.add(getRequest);

我的观点是如何将所有请求代码发送到另一个类,然后实例化该类并调用makeRequest。 我已经尝试了这个,但它失败了。我不知道它是否与Context有关,但它失败了......

我这样做了:

public void onClick(View v) {
    try{

        Utils varRequest = new Utils(getApplicationContext());
        String url = "https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=";

        varRequest.makeRequest(url);
        mitexto.setText(varRequest.miError);
    }
    catch(Exception excepcion) {
        System.out.println(excepcion.toString());

        }

    }

......和Utils类是:

public class Utils {
    public Context contexto;
    public String miError;
    private RequestQueue queue ;

    public Utils (Context contextoInstancia){
        contexto = contextoInstancia;
        queue = Volley.newRequestQueue(contexto);
    }

    public void makeRequest(String url){

        JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                // TODO Auto-generated method stub
                miError="Response => "+response.toString();
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                // TODO Auto-generated method stub
                miError="Response => "+error.networkResponse.toString();
            }
        });

        queue.add(jsObjRequest);
    }
}   

任何人都可以告诉我我做错了什么,或者如何构建代码?

提前致谢。

2 个答案:

答案 0 :(得分:53)

一般来说,分离这类东西是一种很好的做法,所以你要走正确的道路,考虑制作一个处理你请求的singelton类 - 这是 非常一般模板 ,但应该让你的结构继续:

创建一个单例类,当你的应用程序启动时你可以实例化它:

public class NetworkManager
{
    private static final String TAG = "NetworkManager";
    private static NetworkManager instance = null;

    private static final String prefixURL = "http://some/url/prefix/";

    //for Volley API
    public RequestQueue requestQueue;

    private NetworkManager(Context context)
    {
        requestQueue = Volley.newRequestQueue(context.getApplicationContext());
        //other stuf if you need
    }

    public static synchronized NetworkManager getInstance(Context context)
    {
        if (null == instance)
            instance = new NetworkManager(context);
        return instance;
    }

    //this is so you don't need to pass context each time
    public static synchronized NetworkManager getInstance()
    {
        if (null == instance)
        {
            throw new IllegalStateException(NetworkManager.class.getSimpleName() +
                    " is not initialized, call getInstance(...) first");
        }
        return instance;
    }

    public void somePostRequestReturningString(Object param1, final SomeCustomListener<String> listener)
    {

        String url = prefixURL + "this/request/suffix";

        Map<String, Object> jsonParams = new HashMap<>();
        jsonParams.put("param1", param1);

        JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, new JSONObject(jsonParams),
                new Response.Listener<JSONObject>()
                {
                    @Override
                    public void onResponse(JSONObject response)
                    {
                         Log.d(TAG + ": ", "somePostRequest Response : " + response.toString());
                         if(null != response.toString())
                           listener.getResult(response.toString());
                    }
                },
                new Response.ErrorListener()
                {
                    @Override
                    public void onErrorResponse(VolleyError error)
                    {
                        if (null != error.networkResponse)
                        {
                            Log.d(TAG + ": ", "Error Response code: " + error.networkResponse.statusCode);
                            listener.getResult(false);
                        }
                    }
                });

        requestQueue.add(request);
    }
}

当您的申请出现时:

public class MyApplication extends Application
{
  //...

    @Override
    public void onCreate()
    {
        super.onCreate();
        NetworkManager.getInstance(this);
    }

 //...

}

回调的简单侦听器界面(单独的文件会很好):

public interface SomeCustomListener<T>
{
    public void getResult(T object);
}

最后,无论你想要什么,上下文已经在那里,只需调用:

public class BlaBla
{
    //.....

        public void someMethod()
        {
            NetworkManager.getInstance().somePostRequestReturningString(someObject, new SomeCustomListener<String>()
            {
                @Override
                public void getResult(String result)
                {
                    if (!result.isEmpty())
                    {
                     //do what you need with the result...
                    }
                }
            });
        }
}

您可以将任何对象与侦听器一起使用,具体取决于您需要接收的内容,这也适用于经过一些小修改的GET请求(请参阅this SO thread for more about GET),您可以从任何地方调用它(onClicks等) 。),只记得他们需要在方法之间进行匹配。

希望这有助于而且不会太晚!

答案 1 :(得分:2)

我使用一个简单的解决方案。 创建监听器(因为它们是接口,它们不能直接实例化,但可以将它们实例化为实现接口的匿名类)在活动或片段内。 将这些实例作为参数传递给Request。(StringRequest,JsonObjectRequest或ImageRequest)。

public class MainActivity extends Activity {

private static final String URI_WEATHER = "http://marsweather.ingenology.com/v1/latest/";

private Listener<JSONObject> listenerResponse = new Listener<JSONObject>() {

    @Override
    public void onResponse(JSONObject response) {
        Toast.makeText(MainActivity.this, "Resonse " + response.toString(), Toast.LENGTH_LONG).show();
    }
};

private ErrorListener listenerError = new ErrorListener() {

    @Override
    public void onErrorResponse(VolleyError error) {
        Toast.makeText(MainActivity.this, "Error " + error, Toast.LENGTH_LONG).show();

    }
};

}

接下来,创建一个有请求的类,并将此侦听器传递给此类&#39;请求方法,这就是全部。我不解释这部分,这与在任何教程中创建请求对象相同。但您可以根据需要自定义此类。您可以创建单个RequestQueue来检查优先级,或者将身体http体参数设置为此方法作为参数。

public class NetworkManagerWeather {

public static void getWeatherData(int method, Context context, String url,
        Listener<JSONObject> listenerResponse, ErrorListener listenerError) {
    JsonObjectRequest requestWeather = new JsonObjectRequest(Method.GET, url, null, listenerResponse,
            listenerError);
    Volley.newRequestQueue(context).add(requestWeather);
}

}

最后从MainActivity调用此方法以实现instatnce

NetworkManagerWeather.getWeatherData(Method.GET, this, URI_WEATHER, listenerResponse, listenerError);