Android架构MVP模式
todo
Android最初使用的是MVC模式,即Model,View,Controller。
这三个部分是相互调用的,View可以直接调用model,MVC模式的缺点是三个部分互相产生交互,结构混乱.在Android开发中Activity会存在一部分的业务逻辑.作为View的实际承担了Controller的功能,造成Activity的臃肿.
MVP中添加了Prsernter类代替Controller,Model和View之间通过Prsernter控制而不直接交互
Model ←→ Prsernter ←→ View
MVP模式的优点:
- Activity剥离了业务逻辑,只用于展示和事件响应
- 直接对Prsernter的接口,进行单元测试,不需要操作UI
总结
定义一个Connector接口,下属两个子接口分别供V和P继承.V的接口方法定义操作UI.P包含V的引用并调用V的接口方法操作V.在V中新建P并把V的引用赋值给P.V调用P的接口方法来进行获取数据等操作.
碰到的问题是P和V的解耦,ListView和RecyclerView的listData, Adapter, LayoutManager到底是放到View还是Prsenter中的选择.
UI相关的应该全部放到View中,P只进行业务流程相关的操作
分析Google的MVP实例应用代码
定义Contract接口,作为连接View和Presenter的接口,定义一系列方法
public interface TasksContract {
interface View extends BaseView<Presenter> {
void setLoadingIndicator(boolean active);
void showTasks(List<Task> tasks);
void showAddTask();
void showTaskDetailsUi(String taskId);
void showTaskMarkedComplete();
void showTaskMarkedActive();
void showCompletedTasksCleared();
void showLoadingTasksError();
void showNoTasks();
void showActiveFilterLabel();
void showCompletedFilterLabel();
void showAllFilterLabel();
void showNoActiveTasks();
void showNoCompletedTasks();
void showSuccessfullySavedMessage();
boolean isActive();
void showFilteringPopUpMenu();
}
interface Presenter extends BasePresenter {
void result(int requestCode, int resultCode);
void loadTasks(boolean forceUpdate);
void addNewTask();
void openTaskDetails(@NonNull Task requestedTask);
void completeTask(@NonNull Task completedTask);
void activateTask(@NonNull Task activeTask);
void clearCompletedTasks();
void setFiltering(TasksFilterType requestType);
TasksFilterType getFiltering();
}
}
View类继承TasksContract.View接口,实现方法
public class TasksFragment extends Fragment implements TasksContract.View {
@Override
public void showActiveFilterLabel() {
mFilteringLabelView.setText(getResources().getString(R.string.label_active));
}
@Override
public void showCompletedFilterLabel() {
mFilteringLabelView.setText(getResources().getString(R.string.label_completed));
}
@Override
public void showAllFilterLabel() {
mFilteringLabelView.setText(getResources().getString(R.string.label_all));
}
@Override
public void showAddTask() {
Intent intent = new Intent(getContext(), AddEditTaskActivity.class);
startActivityForResult(intent, AddEditTaskActivity.REQUEST_ADD_TASK);
}
}
Presenter类继承TasksContract.Presenter接口并实现方法
public class TasksPresenter implements TasksContract.Presenter {
private final TasksContract.View mTasksView;
public TasksPresenter(@NonNull TasksRepository tasksRepository, @NonNull TasksContract.View tasksView) {
mTasksRepository = checkNotNull(tasksRepository, "tasksRepository cannot be null");
mTasksView = checkNotNull(tasksView, "tasksView cannot be null!");
mTasksView.setPresenter(this);
}
@Override
public void loadTasks(boolean forceUpdate) {
// Simplification for sample: a network reload will be forced on first load.
loadTasks(forceUpdate || mFirstLoad, true);
mFirstLoad = false;
}
}