2015-01-27 16 views
16

Xin chào, tôi muốn môđun hóa các yêu cầu bóng chuyền vì vậy tôi không trộn mã trình diễn hoạt động với các yêu cầu volley. Tất cả các mẫu tôi đã thấy, yêu cầu bóng chuyền đang được đặt - ví dụ- trên sự kiện OnClick từ nút hoạt động.Android Volley - Cách tách biệt các yêu cầu trong một lớp học khác

Ý tôi là mã này (lấy từ nguồn khác):

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

Quan điểm của tôi ở đây là làm thế nào để có được điều này mã tất cả yêu cầu đến một lớp học và chỉ dụ lớp và gọi makeRequest. Tôi đã thử điều này nhưng không thành công. Tôi không biết nếu đó là một cái gì đó liên quan với bối cảnh nhưng nó không thành công ...

Tôi đã làm điều này:

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

     } 

    } 

... và lớp Utils là:

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

Can bất cứ ai cho tôi biết những gì tôi đang làm sai, hoặc làm thế nào để cấu trúc mã?

Xin cảm ơn trước.

+0

async là async ... mitexto.setText (varRequest.miError); nên được gọi trong onResponse hoặc onErrorResponse ... hoặc lớp học có onClick nên triển khai Response.Listener ... – Selvin

+1

hehehe, vì vậy thay vào đó 'Response.Listener ' anh ấy nên sử dụng 'CallBack '? sự khác biệt ở đâu? – Selvin

+2

Tôi nghĩ câu trả lời của Rohit Patil trong http://stackoverflow.com/questions/35628142/how-to-make-separate-class-for-volley-library-and-call-all-method-of-volley-from là một trong những bạn muốn. – SajithK

Trả lời

47

nói chung đó là thực hành tốt để tách loại công cụ này, vì vậy bạn đang ở trên con đường đúng đắn, hãy xem xét thực hiện một lớp singelton để xử lý yêu cầu của bạn - đây là một rất chung chung mẫu, nhưng sẽ nhận được của bạn cấu trúc đi:

tạo ra một lớp singleton, mà bạn instatiate khi bạn đang ứng dụng đi lên:

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

khi ứng dụng của bạn đi lên:

public class MyApplication extends Application 
{ 
    //... 

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

//... 

} 

một giao diện người nghe đơn giản để gọi lại của bạn (file riêng biệt sẽ làm tốt):

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

và cuối cùng, từ bất cứ nơi nào bạn muốn, bối cảnh là đã có trong đó, chỉ cần gọi:

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

bạn có thể sử dụng bất kỳ đối tượng nào với người nghe, tùy thuộc vào những gì bạn cần nhận, điều này cũng hoạt động cho các yêu cầu GET với một số sửa đổi nhỏ, (xem this SO thread for more about GET) và bạn có thể gọi từ mọi nơi (onClicks, v.v.) họ cần phải khớp giữa m ethods.

Hy vọng điều này sẽ giúp và không quá muộn!

+0

Cách tạo 'customlistener'? – Sauron

+0

Đó là giao diện java cơ bản giúp bạn chuyển đối tượng, tạo nó trong một tệp riêng biệt (bạn có thể sao chép dán từ đây, thực sự là tất cả, có thể muốn đổi tên), nhập, và khi bạn khai báo nó như là một đối tượng ẩn danh (ngầm truyền lớp giao diện với 'new customListener ...' khi gọi phương thức yêu cầu mong muốn), tất cả những gì bạn cần làm là ghi đè nó và sử dụng giá trị trả về của nó để tiếp tục làm việc. – TommySM

+0

@TommySM làm cách nào để nhận tiêu đề phản hồi bằng mã trên? – user3197818

2

Tôi sử dụng giải pháp đơn giản cho việc này. Tạo người nghe (vì chúng là giao diện, chúng không thể được khởi tạo trực tiếp nhưng chúng có thể được khởi tạo như một lớp ẩn danh thực hiện giao diện) bên trong hoạt động hoặc đoạn. Chuyển các trường hợp này dưới dạng tham số cho Yêu cầu. (StringRequest, JsonObjectRequest hoặc 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(); 

    } 
}; 

}

Tiếp theo, tạo một lớp học có yêu cầu và vượt qua thính giả này đến lớp phương pháp yêu cầu này, đó là tất cả. Tôi không giải thích phần này cũng giống như việc tạo một đối tượng yêu cầu trong bất kỳ hướng dẫn nào. Nhưng bạn có thể tùy chỉnh lớp này như bạn muốn. Bạn có thể tạo singleton RequestQueue để kiểm tra mức độ ưu tiên hoặc đặt thông số cơ thể http của cơ thể thành phương pháp này làm số liệu.

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

}

Cuối cùng gọi phương pháp này từ MainActivity cho instatnce

NetworkManagerWeather.getWeatherData(Method.GET, this, URI_WEATHER, listenerResponse, listenerError); 
Các vấn đề liên quan