2014-09-12 6 views
0

Я хочу отделить асинхронный http-код от действий, поскольку я повторно использую код. Это то, что я делаю сейчас:Android - отдельный асинхронный http-код из активности в соответствии с принципами SOLID

Я хочу получить список проектов из REST API и сохранить его в массиве. (Предположим, что я не использую локальное кэширование, как я хочу, чтобы загрузить их каждый раз)

ProjectInterface.java

public interface ProjectInterface { 
    public void onProjectsLoaded(ArrayList<Project> projectArrayList); 
} 

HttpProjectList.java

//async class will get the results from the server and send to the activity 
public class HttpProjectList { 

    protected ProjectInterface interface; 
    protected Context c; 

    public HttpProjectList(ProjectInterface interface, Context c){ 
    this.interface = interface; 
    this.c = c; 
    } 

    //Run Async task Volley here 
    public void projectListRequest() {  
    RequestQueue requestQueue = Volley.newRequestQueue(this.c); 
    JsonArrayRequest req = new JsonArrayRequest(Path.WORK_ORDERS, success, error); 
    requestQueue.add(req); 
    } 

//on success set the data 
private Response.Listener<JSONArray> success = new Response.Listener<JSONArray>() { 
    @Override 
    public void onResponse(JSONArray response) { 
     //do dome parsing here and populate the array 
     interface.onProjectsLoaded(projectArrayList); 
    } 
} 

//error function here, i'm not typing 

} 

MyActivity.java

//I'm calling all in this activity 
public class BaseActivity extends Activity implements ProjectInterface { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(setView()); 

    HttpProjectList httpList = new HttpProjectList(this, getBaseContext()); 
    httpList.projectListRequest(); //fire http call 
    } 

    //run after projects loaded 
    @Override 
    public void onProjectsLoaded(ArrayList<Project> projectArrayList) { 
    //Do something with the server data 
    } 

} 

В этом случае у меня есть один API, который заполняет массив. Что делать, если у меня есть несколько вызовов api? Как

  1. Список пользователей
  2. список Подрядчик
  3. Список задач
  4. POST новую задачу на сервер и т.д.

Как я могу организовать код в соответствии с ООП и SOLID принципы? Это те техники, которые у меня есть, но я не знаю, какой из них лучший.

  1. Создайте отдельные классы для всех функций Async. Согласно вышеприведенному примеру, у меня есть 1 интерфейс и 1 класс обработчика HTTP-сервиса. Точно так же я создам 2 набора классов для каждого вызова api.

  2. Создайте один интерфейс HttpInterface и поместите в него все функции обратного вызова и создайте еще один класс HttpHandler и поместите все http-методы всех API-вызовы

Какой из них лучше? Или есть другой способ? Можете ли вы дать совет по этому поводу? Большое спасибо!

ответ

1

Оба предложенных подхода следуют образцу Наблюдателя. Я бы лично предложил второй подход, в котором все методы инкапсулированы в один интерфейс. Однако, если количество методов повышается (скажем, выше 5), то, возможно, вам следует рассмотреть возможность группировки их таким образом, который может отражать функциональность объекта. Например, вы можете иметь:

public interface HttpUserListener { 

    public void onUserListReceived(List<User> users); 
    public void onUserAdd(User user); 
    public void onUserRemove(User user); 
} 


public interface HttpProjectListener { 

    public void onProjectListReceived(List<Project> projects); 
    public void onProjectAssigned(Project project, User user); 
    public void onProjectComplete(Project project); 
} 

На части реализации, возможно, вам нужен список слушателей быть вызван конкретным событием:

public class HttpHandler { 

    protected List<HttpUserListener> userListeners; 
    protected List<HttpProjectListener> projectListeners; 
    protected Context c; 

    public HttpHandler(Context c){ 
    this.c = c; 
    } 

    public void registerListener(UserListener listener){ 

    if(userListeners == null){ 

     userListeners = new ArrayList<UserListener>(1); 
    } 
    userListener.add(listener); 
    } 

    public void unregisterListener(UserListener listener){ 

    if(userListeners == null){ 
     return; 
    } 
    userListener.remove(listener); 
    } 

    public void asyncAddUser(User user){ 

    // provide the async method and call the listeners 
    if(userListeners != null) 
     for(UserListener l: userListeners) 
     l.onUserAdd(user); 
    } 

} 

Я хочу подчеркнуть, что идеальным местом создания и обработки Асинхронные задачи в Android - это службы. поэтому HttpHandler будет расширять Service (или IntentService, который уже предоставляет рабочий поток), и вы можете зарегистрировать и отменить регистрацию слушателей этой службы, используя метод привязки.This - хороший учебник с сайта разработчиков Android.

В качестве альтернативы вы можете забыть о традиционном подходе слушателя и иметь одну услугу, которая будет транслировать намерения, когда происходит HTTP-вызов. И ваши действия захватывают эти трансляции и соответственно реагируют. Это ближе к архитектуре программирования Android.