Android MVP 架构介绍与使用入门

MVP 与 MVC 简介MVP 软件架构在现在的应用中,特别是 Android 端的编程中尤为突出的使用,因为 MVP 架构可以很深层次的去解耦视图、业务逻辑、数据源三者的关系,让它们之间的相互依赖性降低 。MVP 是针对 Android 端开发而言的,它其实是 MVC 演变过来的,因为 MVC 模式在 Android 开发中并不是那么愉快 。主要表现方面,比如,我们在写一个功能模块时,Activity 中的代码很容易就突破到上千甚至上万行,除了必要的 findviewid,listener 等,其他的代码几乎都是业务逻辑相关的,这就显得 Activity 非常的臃肿,也不是说不可以,但是在模块升级时造成业务逻辑的改变,我们就需要去成千上万行的 Activity 中寻找业务逻辑代码,这就有可能出现多处代码需要修改,不细心的话,非常容易出 Bug,而且除了 Bug 代码也不好定位 。
第二个问题,数据源(来自数据库或这网络)部分可能会写好几份,比如,有两个 Activity 同时有着个人信息数据要显示,我必须在这两个 Activity 中各请求一次网络或者访问数据库,得到最新的数据,这就出现了代码重复的问题 。
带着这两个问题,我们来看看 MVP 架构能够怎样帮助我们解决 MVC 出现的这种问题!首先,我来简单的介绍一下 MVC 它指的是:

  • model(模型),负责访问网络数据、访问数据库数据,提供数据源
  • view(视图),负责更新界面、响应用户界面操作
  • controller(控制器),负责业务逻辑控制,处理数据
我们在 Android 开发中,Activity 负责 UI 显示及更新操作,相当于 View 层,我们一般都会把代码直接写在 Activity 中,不管是数据源、逻辑控制、数据处理等操作一个劲的往 Activity 里写,那么它们三者的关系都互相依赖,你中有我,我中有你,它们就形成了三角的关系 。
Android MVP 架构介绍与使用入门

文章插图
 
这样的关系,导致 Activity 代码量过于庞大,修改和维护起来比较困难 。这样的三角恋关系,显然不是长久之际 。于是,MVP 它就强行把 View 与 Model 隔离了,让它们不再有联系,传说中的 Presenter 就是脚踏两只船,来回奔走于 View 与 Model 之间的契约者、联系者 。
Android MVP 架构介绍与使用入门

文章插图
 
MVP(model、view 、presenter),将 Activity 中的代码抽离了出来,把 Activity(Fragment、View) 只当作 View 层,通过一个 Presenter(契约层)将 View 和 Model 层联系起来,让 View 和 Model 层充分的解耦 。
我们访问网络得到数据并显示出来会是这样一个流程:
  1. Activity 启动时,告诉 Presenter 我要数据了
  2. Presenter 就会叫 Model 去访问数据接口得到数据
  3. Model 得到原数据就交给 Presenter 了,Presenter 一看数据不规范,赶紧处理一下,处理完成
  4. Presenter 就把处理后的数据汇报给 Activity(View),View 拿到数据就做显示的操作,工作结束
MVC下面我们通过一个简单的案例来进行了解 MVP 架构的代码写法,当然,这里的写法不唯一,因为每个人写代码的方式都是不一样的,最核心的是 MVP 架构的思想,把思想转为实际代码,这才是值得我们探索和学习的地方 。
来看看代码,我们在网络请求时,获取到数据,并 toast 和显示到 textview 上,这样的代码我相信谁都会写,但一般人都是直接一口气写在 MainActivity 类上面,比如这样:
public class MainActivity extends AppCompatActivity {private TextView tv; private static final String TAG = "MainActivity";@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);initViews();request(); showDialog(); }private void initViews() { tv = findViewById(R.id.tv); }private void showDialog() { ProgressDialog dialog = new ProgressDialog(this); dialog.show(); new Handler().postDelayed(new Runnable() { @Override public void run() { dialog.dismiss(); } }, 1500); }private void request() { OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://www.baidu.com/") .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { }@Override public void onResponse(Call call, Response response) throws IOException { String resp = response.body().string(); toast(resp); } }); }private void toast(String resp) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "" + resp, Toast.LENGTH_SHORT).show(); tv.setText(resp); } }); } }它的效果其实就是请求百度首页,返回网页数据以 string 方式显示出来而已 。


推荐阅读