Android Volley – как изолировать запросы в другом классе

Привет, я хотел бы модулизовать запросы волейбола, поэтому я не смешиваю код представления активности с запросами на волейбол. Все образцы, которые я видел, запрос на залп помещаются, например, в событие OnClick из кнопки активности.

Я имею в виду этот код (взятый из источника diff):

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

Может ли кто-нибудь сказать мне, что я делаю неправильно, или как структурировать код?

Заранее спасибо.

Solutions Collecting From Web of "Android Volley – как изолировать запросы в другом классе"

В общем, это хорошая практика, чтобы разделить такие вещи, так что вы на правильном пути, подумайте над тем, чтобы создать класс 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 с некоторыми незначительными изменениями (см. Этот поток SO для получения более подробной информации о GET ), и вы можете вызывать это извне (onClicks и т. Д.). ), Просто помните, что они должны совпадать между методами.

Надеюсь, это поможет, и не слишком поздно!

Для этого я использую простое решение. Создайте Listeners (поскольку они являются интерфейсом, они не могут быть созданы напрямую, но могут быть созданы как анонимный класс, реализующий интерфейс) внутри действия или фрагмента . Передайте эти экземпляры в качестве параметров для запроса. (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(); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } 

}

Затем создайте класс, у которого есть запрос, и передайте этим слушателям метод запроса этого класса, вот и все. Я не объясняю эту часть, это то же самое, что и создание объекта запроса в любом учебнике. Но вы можете настроить этот класс по своему усмотрению. Вы можете создать singleton 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);