2016-11-12 25 views
7

Używam EventBus do powiadamiania Activity/Fragment, gdy otrzymam odpowiedź z serwera. Wszystko do tej pory działa dobrze, ale problem pojawia się, gdy odbieram dwie rozmowy sieciowe w tym samym Fragment lub Activity. Problem polega na tym, że otrzymujemy wywołania obu odpowiedzi z serwera. Odpowiedź call 1 jest inna niż call 2.Jak używać typu wywołania z EventBus

Wpadłem na rozwiązanie - dodałem CallType w NetworkReqest, ale nie mogę powiadomić działania/fragmentu o wywołaniu sieciowym, ponieważ post() zajmuje tylko jeden parametr.

Oto odpowiedni kod -

public class NetworkRequest { 
    EventBus eventBus = EventBus.getDefault(); 

    public void stringParamRequest(String url, final Map<String, String> params,String callType) { 
     StringRequest jsonObjRequest = new StringRequest(Request.Method.POST, url, 
       new Response.Listener<String>() { 
        @Override 
        public void onResponse(String response) { 
         eventBus.post(response); 
        } 
       }, new Response.ErrorListener() { 

      @Override 
      public void onErrorResponse(VolleyError error) { 
       VolleyLog.d("volley", "Error: " + error.getMessage()); 
       eventBus.post(error); 
      } 
     }) { 

      @Override 
      public String getBodyContentType() { 
       return "application/x-www-form-urlencoded; charset=UTF-8"; 
      } 

      @Override 
      protected Map<String, String> getParams() throws AuthFailureError { 
       Map<String, String> param = params; 
       return param; 
      } 

     }; 
     SkillSchoolApplication.get().addToRequestQueue(jsonObjRequest); 
    } 

    public void stringRequest(String url, String callType) { 
     StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() { 
      @Override 
      public void onResponse(String response) { 
       eventBus.post(response); 
      } 
     }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 

      } 
     }); 
     SkillSchoolApplication.get().addToRequestQueue(stringRequest); 
    } 


} 

Metoda Wewnątrz fragment/activity Tutaj powstaje problem, gdy po otrzymaniu odpowiedzi od jednego żądania i ogień kolejny wniosek, który jest zależny od respose pierwszego wniosku

@Subscribe(threadMode = ThreadMode.MAIN) 
    public void onEvent(String response) { 
     Log.d(TAG, response); 
     boolean isCourseAvaible = false; 
     if (!isCourseAvaible) { 
      isCourseAvaible = true; 
      List<CoursesDTO> coursesDTOs = AppMgr.coursesMgr(response); 
      String[] ids = new String[0]; 
      String id; 
      if (coursesDTOs != null) { 
       ids = new String[coursesDTOs.size()]; 
       for (int i = 0; i < coursesDTOs.size(); i++) { 
        ids[i] = coursesDTOs.get(i).getListId(); 

       } 
      } 
      id = TextUtils.join(",", ids); 
      Map<String, String> map = new HashMap<>(); 
      map.put("part", "snippet,contentDetails"); 
      map.put("playlistId", id); 
      map.put("key", AppConstants.YOUTUBE_KEY); 
      NetworkRequest networkRequest = new NetworkRequest(); 
      networkRequest.stringParamRequest("some url", map); 
     } else { 
      Log.d(TAG, response); 
     } 

    } 

    @Subscribe(threadMode = ThreadMode.MAIN) 
    public void onEvent(VolleyError error) { 
     Log.d(TAG, error.toString()); 
     Toast.makeText(getActivity(), "Something went wrong " + error.toString(), Toast.LENGTH_SHORT).show(); 
    } 

Jak mogę rozróżnić callType w ramach onEvent(). Wymagane są pewne wskazówki. Dzięki wielkie.

Odpowiedz

3

Jedną z opcji jest zawarcie dwóch potrzebnych danych w klasie i przekazanie ich do magistrali zdarzeń. Pozostawienie prywatnych członków, pobierających/ustawiających i konstruktorów dla zwięzłości.

class NetworkResponse() { 
    public String callType; 
    public String response; 
} 

Po otrzymaniu odpowiedzi, przydzielić NetworkResponse i wypełnić go z odpowiedzią i rodzaju połączenia i post że do autobusu konferencyjnego.

@Subscribe(threadMode = ThreadMode.MAIN) 
public void onEvent(NetworkResponse networkResponse) { 
    if(networkResponse.callType.equals(CALL_1)) { 
    // ... 
    } else if (networkResponse.callType.equals(CALL_2)) { 
    // ... 
    } 

} 
+0

Myślałem o tym, ale myślałem, że może być lepsze rozwiązanie. –

1

Serializuj odpowiedź łańcuchową do komponentu bean Java w metodzie onResponse i wysyłaj odpowiedni obiekt do widoków. Aktywności, fragmenty i widoki nie muszą wiedzieć o serializacji, a poza tym wydajność Twojej aplikacji może się poprawić, ponieważ możesz zmodyfikować swój kod, aby serializować dane w wątku tła.

public void stringRequest(String url, String callType) { 
     StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() { 
      @Override 
      public void onResponse(String response) { 
       eventBus.post(AppMgr.coursesMgr(response)); 
      } 
     }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 

      } 
     }); 
     SkillSchoolApplication.get().addToRequestQueue(stringRequest); 
    } 

Wtedy Twoja pierwsza subskrypcja wydarzenie będzie wyglądać następująco:

@Subscribe(threadMode = ThreadMode.MAIN) 
    public void onEvent(List<CoursesDTO> coursesDTOs) { 
     Log.d(TAG, response); 
     boolean isCourseAvaible = false; 
     if (!isCourseAvaible) { 
      isCourseAvaible = true; 
      String[] ids = new String[0]; 
      String id; 
      if (coursesDTOs != null) { 
       ids = new String[coursesDTOs.size()]; 
       for (int i = 0; i < coursesDTOs.size(); i++) { 
        ids[i] = coursesDTOs.get(i).getListId(); 
       } 
      } 
      id = TextUtils.join(",", ids); 
      Map<String, String> map = new HashMap<>(); 
      map.put("part", "snippet,contentDetails"); 
      map.put("playlistId", id); 
      map.put("key", AppConstants.YOUTUBE_KEY); 
      NetworkRequest networkRequest = new NetworkRequest(); 
      networkRequest.stringParamRequest("some url", map); 
     } else { 
      Log.d(TAG, response); 
     } 
    } 

i można mieć drugi, inny, abonament String. Ale skoro i tak zamierzasz wykonać drugie połączenie, najlepiej jest wykonać je bezpośrednio po uzyskaniu prawidłowej odpowiedzi od pierwszej.

public class NetworkRequest { 
    EventBus eventBus = EventBus.getDefault(); 

    public void stringParamRequest(String url, final Map<String, String> params,String callType) { 
     StringRequest jsonObjRequest = new StringRequest(Request.Method.POST, url, 
       new Response.Listener<String>() { 
        @Override 
        public void onResponse(String response) { 
         eventBus.post(response); 
        } 
       }, new Response.ErrorListener() { 

      @Override 
      public void onErrorResponse(VolleyError error) { 
       VolleyLog.d("volley", "Error: " + error.getMessage()); 
       eventBus.post(error); 
      } 
     }) { 

      @Override 
      public String getBodyContentType() { 
       return "application/x-www-form-urlencoded; charset=UTF-8"; 
      } 

      @Override 
      protected Map<String, String> getParams() throws AuthFailureError { 
       Map<String, String> param = params; 
       return param; 
      } 

     }; 
     SkillSchoolApplication.get().addToRequestQueue(jsonObjRequest); 
    } 

    public void stringRequest(String url, String callType) { 
     StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() { 
      @Override 
      public void onResponse(String response) { 
       List<CoursesDTO> coursesDTOs = AppMgr.coursesMgr(response); 
       String[] ids = new String[0]; 
       String id; 
       if (coursesDTOs != null) { 
       ids = new String[coursesDTOs.size()]; 
       for (int i = 0; i < coursesDTOs.size(); i++) { 
        ids[i] = coursesDTOs.get(i).getListId(); 

       } 
       } 
       id = TextUtils.join(",", ids); 
       Map<String, String> map = new HashMap<>(); 
       map.put("part", "snippet,contentDetails"); 
       map.put("playlistId", id); 
       map.put("key", AppConstants.YOUTUBE_KEY); 
       NetworkRequest networkRequest = new NetworkRequest(); 
       networkRequest.stringParamRequest("some url", map);     
      } 
     }, new Response.ErrorListener() { 
      @Override 
      public void onErrorResponse(VolleyError error) { 

      } 
     }); 
     SkillSchoolApplication.get().addToRequestQueue(stringRequest); 
    } 
} 

Wreszcie, dwie linie

boolean isCourseAvaible = false; 
     if (!isCourseAvaible) { 

są zbędne, to jakby mieć żadnego warunku.