本文使用kotlin代码来写的,在项目中 View 和 Model 并不直接交互,而是使用 Presenter 作为 View 和 Model 之间的桥梁。其中 Presenter 中同时持有 View 层以及 Model 层的 Interface 的引用,而 View 层持有 Presenter 层 Interface 的引用,当 View 层某个页面需要展示某些数据的时候,首先会调用Presenter 层的某个接口,然后 Presenter 层会调用 Model 层请求数据,当 Model 层数据加载成功之后会调用 Presenter 层的回调方法通知 Presenter 层数据加载完毕,最后 Presenter 层再调用 View 层的接口将加载后的数据展示给用户。这就是 MVP 模式的核心过程。
这样分层的好处就是大大减少了Model与View层之间的耦合度。一方面可以使得View层和Model层单独开发与测试,互不依赖。另一方面Model层可以封装复用,可以极大的减少代码量。当然,MVP还有其他的一些优点,这里不再赘述。
Base基类
BaseView:用于创建基类View,统一管理view; BasePresenter:所有Presenter层的抽象类,负责Model、View层的引用和销毁;我们来看看项目结构: 接下来看看各个类的代码 MainContract
/** * 契约接口,可以很直观的看到 M、V、P 层接口中提供的方法 */ interface MainContract { interface IMainModel { fun getDataFromModel(callback: (String?) -> Unit) } interface IMainView { fun showDialog() fun updataUI(content: String?) } interface IMainPresenter { fun handlerData() } }MainActivity
/** * MVP 的写法,Version 1: 基础写法 */ class MainActivity : AppCompatActivity(), MainContract.IMainView { private var mPresenter: MainPresenter? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) mPresenter = MainPresenter(this) mPresenter!!.handlerData() } override fun showDialog() { val dialog = ProgressDialog(this) dialog.show() Handler().postDelayed({ dialog.dismiss() }, 1500) } override fun updataUI(content: String?) { runOnUiThread { Toast.makeText(this@MainActivity, "" + content, Toast.LENGTH_SHORT).show() tv!!.text = content } } }MainPresenter
/** * presenter 层,承担业务逻辑处理,数据源处理等 */ class MainPresenter(private val mView: MainContract.IMainView?) : MainContract.IMainPresenter { private val mModel: MainContract.IMainModel init { mModel = DataModel() } override fun handlerData() { mView?.showDialog() //发起请求,获得回调数据 mModel.getDataFromModel { //经过对数据处理,非空处理,逻辑判断等等,最后更新UI mView?.updataUI(it) } } }DataModel
/** * model 层,请求网络或数据库,提供数据源(原始数据) */ class DataModel : MainContract.IMainModel { override fun getDataFromModel(callback: (String?) -> Unit) { //此处经过网络请求,获取到数据之后,返回去 callback("返回数据:123456") } }activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".v1.view.MainActivity"> <TextView android:id="@+id/tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>关于封装baseMvp,过程有点多,这里就不做详细的介绍,下面来看看项目结构图
加入一个我自己封装的volley网络请求工具类volleyUtil,用作请求响应的展示。 需要retrofit的同学,可以到我的另外一篇博客里看 最后全部的代码都在这里:https://download.csdn.net/download/wy313622821/12812143
