【问题标题】:Android Volley - How to isolate requests in another classAndroid Volley - 如何隔离另一个类中的请求
【发布时间】:2015-03-26 04:28:57
【问题描述】:

您好,我想将 volley 请求模块化,这样我就不会将活动演示代码与 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。 我已经尝试过了,但它失败了。我不知道它是否与上下文相关,但它失败了......

我这样做了:

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);
    }
}   

谁能告诉我我做错了什么,或者如何构造代码?

提前致谢。

【问题讨论】:

  • 异步是异步的 ... mitexto.setText(varRequest.miError);应该在 onResponse 或 onErrorResponse 中调用...或者具有 onClick 的类应该实现 Response.Listener ...
  • 呵呵呵呵,所以Response.Listener&lt;T&gt;他应该改用CallBack&lt;T&gt;?区别在哪里?
  • 我认为 Rohit Patil 在stackoverflow.com/questions/35628142/… 中的回答是您想要的。

标签: android android-volley


【解决方案1】:

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

创建一个单例类,在应用程序启动时将其实例化:

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 等) ,请记住它们需要在方法之间进行匹配。

希望这会有所帮助,不要太迟!

【讨论】:

  • customlistener 是如何创建的?
  • 这是一个基本的java接口,可以帮助你传输一个对象,在一个单独的文件中创建它(你可以从这里复制粘贴它,实际上就是它的全部内容,可能需要更改名称) ,导入它,并且当您将其声明为匿名对象时(在调用所需的请求方法时隐式传递带有 'new customListener...' 的接口类),您剩下要做的就是覆盖它并使用它的返回值继续工作。
  • @TommySM 如何使用上述代码获取响应标头?
  • @TommySM 内存中对requestQueueinstance 的引用是否可能为空?如果我没记错的话,这可能发生在应用程序在后台但操作系统需要清理资源时。我担心的是,操作系统会清除这些资源,然后下次用户打开应用程序发出请求时,instance 将为空。
【解决方案2】:

我为此使用了一个简单的解决方案。 创建监听器(因为它们是接口,所以不能直接实例化,但可以实例化为实现接口的匿名类)在活动或片段中。 将这些实例作为参数传递给请求。(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();

    }
};

}

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

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 调用这个方法进行实例化

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多