认识GOOGLE官方架构MVP
2017-05-27 00:00
309 查看
认识GOOGLE官方架构MVP
MVP框架简述MVP框架分析
实战示范
参考内容
MVP框架简述
MVP由model–view–controller (MVC)软件模式衍生而来,是一个把view从底层分离出来的一种轻量模型。M(model)代表的是将会显示在view(UI)中的数据。
V(view)是显示数据(model)并且将用户指令(events)传送到presenter以便作用于那些数据的一个接口。View通常含有Presenter的引用。
P(presenter)起到控制的作用,是一个中转元素(如 MVC中的controller),且presenter同时引用view和model。
MVP框架分析
Presenter解耦Presenter起到的就是转发和控制的作用,如果采用传统的OnClickListener监听来代替Presenter,则无法对View内部元素进行合理的控制,控制逻辑复杂。而Presenter了解View的内部结构,可以有效地进行控制,并保证低耦合。
加之,Presenter不应被绑定到Android平台,Presenter的内容应该是普遍意义上能与其他任何java应用共享的java代码。
View自主权
View只执行Presenter指示的操作,即完全依靠Presenter的控制进行工作,所以在进行接口设计时,应该让Presenter控制View的方式更加抽象,粒度不能够太小。
类图及分析如下
- BaseView
界面需要提供的方法中会有很多类似的,把它们提取到一个公共的父类接口中。比如setPresenter方法,其他的view层接口就可以直接继承BaseView接口,不必做重复工作。
public interface BaseView<T> { void setPresenter(T presenter); }
BasePresenter
同理,BasePresenter提供重复的Presenter接口。
public interface BasePresenter { void start(); }
Contract
工程中,每一个模块都有一个自己的Contract接口,Contract包涵了Presenter和View,Presenter实现的逻辑层方法,View实现的界面层的方法都能在Contract接口中一目了然的看明白,具体的Presenter和View的实现类都是通过实现Contract接口来完成。这种管理办法使得开发和维护十分简单。
public interface XXXContract { interface View extends BaseView<Presenter> { } } interface Presenter extends BasePresenter { } }
实战示范
项目目录注:实例来自笔者亲身参与的一款运动体验项目
项目结构的组织方式基本按照功能进行划分,之后我们具体关注login模块中MVP的实现用于理解MVP的实现流程。
LoginContract
具体login任务的Presener和View接口,Presenter接口里面封装的是数据获取的方法,需要数据提供者具体实现;View里面封装是界面层(Fragment)要实现的方法。
public interface LoginContract { interface View extends BaseView<Presenter> { /** * 设置加载提示符 */ void showLoadingIndicator(); /** * 设置出错信息 */ void showErrorInfo(); } interface Presenter extends BasePresenter { boolean checkAccount(String username, String password); } }
LoginPresenter
继承LoginContract.Presenter接口,实现具体的功能方法,代码不再赘述。
LoginActivity
在MVP架构中,个人理解Activity主要负责控制,Fragment负责展示,当然MVP只是一种思想,代码书写的方式因人而异。
LoginActivity的主要只能有初始化Fragment并创建Presenter。
public class LoginActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.login_act); LoginFragment loginFragment = (LoginFragment) getSupportFragmentManager().findFragmentById(R.id.layout_login_content); if (loginFragment == null) { loginFragment = loginFragment.newInstance(); ActivityUtils.addFragmentToActivity(getSupportFragmentManager(), loginFragment, R.id.layout_login_content); } new LoginPresenter(loginFragment); } }
LoginFragment
LoginFragment是View接口的实现类,其不与Model层进行交互,只和presenter的实例进行交互。
LoginFragment持有相应LoginPresenter的引用,通过view的setPresenter方法完成实例的关联操作。当LoginFragment收到界面操作请求即通过LoginPresenter完成逻辑上的处理。
public class LoginFragment extends Fragment implements LoginContract.View { private LoginContract.Presenter mPresenter; private EditText edtTxt_userName; private EditText edtTxt_passWord; private Button btn_login; private Button btn_noAccount; public static LoginFragment newInstance() { return new LoginFragment(); } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.login_frag, container, false); return root; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); btn_login = (Button) getActivity().findViewById(R.id.btn_login); btn_noAccount = (Button) getActivity().findViewById(R.id.btn_noAccount); edtTxt_userName = (EditText) getActivity().findViewById(R.id.edtTxt_userName); edtTxt_passWord = (EditText) getActivity().findViewById(R.id.edtTxt_passWord); btn_login.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { boolean loginResult = mPresenter.checkAccount(edtTxt_userName.getText().toString(), edtTxt_passWord.getText().toString()); if (loginResult) { getActivity().finish(); Intent intent = new Intent(getActivity(), HomePageActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); } } }); btn_noAccount.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getActivity(), RegisterActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); } }); } @Override public void onResume() { super.onResume(); mPresenter.start(); } @Override public void onStop() { super.onStop(); edtTxt_userName.setText(""); edtTxt_passWord.setText(""); } @Override public void showLoadingIndicator() { Toast.makeText(getActivity().getApplicationContext(), "登录成功",Toast.LENGTH_SHORT).show(); } @Override public void showErrorInfo() { Toast.makeText(getActivity().getApplicationContext(), "用户名或密码错误",Toast.LENGTH_SHORT).show(); } @Override public void setPresenter(LoginContract.Presenter presenter) { mPresenter = presenter; } }
参考内容
Github文章:https://github.com/hehonghui/android-tech-frontier架构图片:http://justjavac.iteye.com/blog/1998210
相关文章推荐
- 基于Android真实项目教你一步一步搭建架构2 -- Google官方Mvp架构
- Google官方MVP+Dagger2架构详解
- [译]Google官方关于Android架构中MVP模式的示例
- Google官方MVP+Dagger2架构详解----非常详细,值得多看几遍(okhttp cache)
- MVP解析前言 从Google推出官方MVP架构demo到现在大概有一年多的时间了,半年前大概在所有的Android技术社区都有提到MVP架构,
- google 官方 mvp架构解读,与简单实现
- Google官方MVP+Dagger2架构详解
- google官方架构MVP解析与实战-(从零开始搭建android框架系列(3))
- google官方架构MVP解析与实战-(从零开始搭建android框架系列(3))
- google官方架构MVP解析与实战-(从零开始搭建android框架系列(3))
- 从Dagger2基础到Google官方架构MVP+Dagger2架构详解
- Google 官方Android MVP架构实践
- google官方架构MVP解析与实战【从零开始搭建android框架系列(3)】
- Google官方MVP+Dagger2架构详解【从零开始搭建android框架系列(6)】
- Google官方MVP+Dagger2架构详解
- Google官方关于Android架构中MVP模式的示例
- Google官方关于Android架构中MVP模式的示例续-DataBinding
- Google官方MVP+Dagger2架构 dagger2详解
- Google官方架构MVP解析与实战
- 从Dagger2基础到Google官方架构MVP+Dagger2架构详解