项目有更新(解耦),具体使用参照github项目,地址:https://github.com/wz1509/Base-Mvp,欢迎star/fork
对于一个应用而言我们需要对它抽象出各个层面,而在MVP架构中它将UI界面和数据进行隔离,所以我们的应用也就分为三个层次。
下面通过MVP结构图来看一下MVP中各个层次之间的关系。
在MVP架构中将这三层分别抽象到各自的接口当中。通过接口将层次之间进行隔离,而Presenter对View和Model的相互依赖也是依赖于各自的接口。这点符合了接口隔离原则,也正是面向接口编程。在Presenter层中包含了一个View接口,并且依赖于Model接口,从而将Model层与View层联系在一起。而对于View层会持有一个Presenter成员变量并且只保留对Presenter接口的调用,具体业务逻辑全部交由Presenter接口实现类中处理。
BaseContract
interface BaseContract {
/**
* View通用方法
*/
interface View {
fun showLoading()
fun hideLoading()
fun onApiFail(msg: String)
}
/**
* Presenter通用方法
*/
interface Presenter: LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun detachView()
}
interface Model {
fun onDestroy()
}
}
这里的三个接口作为项目的通用接口。
BaseModel
abstract class BaseModel : BaseContract.Model {
val disposables: CompositeDisposable by lazy(LazyThreadSafetyMode.NONE) {
CompositeDisposable()
}
val apiService: ApiService by lazy(LazyThreadSafetyMode.NONE) {
AppApplication.appApplication.applicationComponent.getApiService()
}
override fun onDestroy() = disposables.clear()
}
实现BaseContract.Model接口onDestroy()方法,用于取消网络。apiService 懒加载实例化是Application中 dagger2 注入的,具体 dagger2用法这里不做叙述。
BasePresenter
abstract class BasePresenter(private var view: BaseContract.View?,
private val model: BaseContract.Model) : BaseContract.Presenter {
override fun detachView() {
model.onDestroy()
view = null
}
}
BasePresenter继承于BaseContract.Presenter实现detachView()方法,用于销毁view和取消网络。这里BaseContract.Presenter接口是继承LifecycleObserver接口,如果在activity/fragment中添加了观察者对象 lifecycle.addObserver(presenter) ,那么presenter是具有activity/fragment生命周期变化的回调通知。
BaseMvpActivity
abstract class BaseMvpActivity.Presenter> : BaseActivity(), BaseContract.View {
@Inject lateinit var presenter: P
private val dialog by lazy { AlertDialog.Builder(this).create() }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
injectPresenter()
lifecycle.addObserver(presenter)
}
fun getActivityComponent(view: ViewModule): ActivityComponent {
return DaggerActivityComponent.builder()
.applicationComponent(AppApplication.get(this).applicationComponent)
.activityModule(ActivityModule(this))
.modelModule(ModelModule())
.viewModule(view)
.build()
}
override fun showLoading() {
dialog.setTitle("title")
dialog.setMessage("加载中...")
dialog.show()
}
override fun hideLoading() {
dialog.dismiss()
}
abstract fun injectPresenter()
}
BaseMvpActivity用于提供injectPresenter()方法用于实例化presenter,onCreate()中添加观察者,用于观察生命周期变化。这里getActivityComponent(view: ViewModule)方法是用dagger2注入model和injectPresenter()方法中注入View。
MainContract
interface MainContract {
interface View : BaseContract.View {
fun onResult(result: String)
}
/**
* 如果后面继承了 BasePresenter,这里就不需要重复继承 BaseContract.Presenter
*/
interface Presenter {
fun getToday()
}
interface Model : BaseContract.Model {
fun getToday(callback: ResultCallBack)
}
}
MainModel
class MainModel : BaseModel(), MainContract.Model {
override fun getToday(callback: ResultCallBack<String>) {
apiService.getToday()
.doOnSubscribe { disposables.add(it) } // 将disposable添加到容器中
.compose(RxHelper.ioMain()) // 这里是io-main线程切换
.subscribe({
val jsonElement = JsonParser().parse(it.string())
val result = GsonBuilder().setPrettyPrinting().create().toJson(jsonElement)
callback.onSuccess(result)
}, {
callback.onFail(ApiCodeException.checkException(it))
})
}
}
ModelModule
@Module
class ModelModule {
@Provides
fun provideMainModel(): MainContract.Model = MainModel()
}
ViewModule
@Module
class ViewModule(private val mainView: MainContract.View){
@Provides
fun provideMainView() = mainView
}
MainPresenter
class MainPresenter @Inject constructor(
private var model: MainContract.Model, private var view: MainContract.View
) : BasePresenter(view, model), MainContract.Presenter {
override fun getToday() {
view.showLoading()
model.getToday(object : ResultCallBack.SimpleResultCallBack<String>() {
override fun onSuccess(data: String) {
view.onResult(data)
view.hideLoading()
}
override fun onFail(errorMsg: String) {
view.onApiFail(errorMsg)
view.hideLoading()
}
})
}
}
MainActivity
class MainActivity : BaseMvpActivity<MainPresenter>(), MainContract.View {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
request_network.setOnClickListener {
presenter.getToday()
}
to_fragment.setOnClickListener {
// this.finish()
startActivity(Intent(this@MainActivity, FrameActivity::class.java))
}
}
override fun injectPresenter() {
getActivityComponent(ViewModule(this))
.inject(this)
}
override fun onResult(result: String) {
content_text.text = result
}
override fun onApiFail(msg: String) {
content_text.text = msg
}
}
通过MVP架构的使用可以看出对于各个层次之间的职责更加单一清晰,同时也很大程度上降低了代码的耦合度。但任何架构都有利有弊,MVP模式在使各层职责单一的条件下项目中类的数量也增多了,由于大部分都是调用接口使得调试中跳转往往跳转到接口中,而接口实现类的代码却看不到,增加了调试负担。最近google新出的Jetpack架构模式也可以试试。
项目地址:https://github.com/wz1509/Base-Mvp
喜欢的话 给个star支持吧 (=・ω・=)