Kotlin-MVP框架

作者: Taonce | 来源:发表于2018-10-31 19:31 被阅读19次

这段时间在写基于gank API客户端Demo的时候,尝试着封装了一把MVP,下面就来谈谈这整个过程中的一些感想。


MVP

说起MVP,大家都是熟悉的不能再熟悉的了,但是要封装一套好的MVP还是很有必要的,可以很快捷的开发项目。下面谈谈我对MVP的理解吧。

mvp.png

View层:取数据和显示界面,问P层索要数据,在界面上显示数据。

Presenter层:把View需要的操作传递给Model层,然后Model层处理完复杂操作之后通过P层来把结果传递给View层。

Model层:P层让我干什么我就干什么,有什么用和怎么用不需要管,只管处理,然后把处理后的结果回调给P层。

了解了三者的基本关系之后,接着来看看具体如何封装属于自己的MVP结构。我这里是按照自己的需求,大家仅供参考!

Demo整体结构如下:

demo.png

整个项目按照上图结构设计。

下面介绍两个比较重要的地方:IBaseViewBasePresenter

IBaseView:

其中IBaseView里面写了两个通用方法:在请求网络的时候用到的通用方法,显示和隐藏进度条。

interface IBaseView{
    fun showLoading()

    fun hideLoading()

}

当我们在实现具体I***View时,只需继承它就行了,不必每次都把showLoadinghideLoading写一遍,如:

interface IMainView : IBaseView {
    fun showAndroidData(bean: AndroidBean)

    fun showErrorMsg(msg: String = "亲,网络出现问题了哦~")
}

这是demo中的一个,另外定义了两个方法,一个是展示获取的Android数据,还有一个就是获取数据失败的方法。显示和隐藏进度条就交给IBaseView来实现。

BasePresenter:

BasePresenter里面实现了P层和V层的绑定和解绑,这里需要知道,在MVP结构中,P和V是双向绑定的,如果我们只绑定不解绑的话,在activity已经销毁的情况下,Presenter如果还在执行操作,那么就会造成activity无法被释放的问题,产生内存泄漏。所以这里一定要注意P和V的解绑,具体实现是在BaseActivity中统一处理。具体代码如下:

package com.taonce.kotlindemo.base

open class BasePresenter<V> {

    private var view: V? = null
    
    // 绑定View
    fun attachView(view: V) {
        this.view = view
    }

    // 解绑
    fun detachView() {
        this.view = null
    }

    fun isAttach(): Boolean {
        return view != null
    }

}

IBaseView一样,在实现具体的***Presenter的时候,也只需要继承BasePresenter就ok了。只需要另外加上自己的逻辑,不考虑每次的V和P的解绑。如:

package com.taonce.kotlindemo.presenter

import com.taonce.kotlindemo.base.BasePresenter
import com.taonce.kotlindemo.bean.AndroidBean
import com.taonce.kotlindemo.model.MainModel
import com.taonce.kotlindemo.contract.IMainModel
import com.taonce.kotlindemo.contract.IMainView

class MainPresenter(mView: IMainView) : BasePresenter<IMainView>(), IMainModel.OnGetAndroidDataListener {

    private var mView: IMainView? = mView
    private var mModel: IMainModel? = null

    init {
        mModel = MainModel()
    }

    fun getAndroidData(category: String, page: Int) {
        this.mView?.showLoading()
        this.mModel?.getAndroidData(category, page, this)
    }

    override fun onGetAndroidDataFinished(bean: AndroidBean?) {
        this.mView?.hideLoading()
        if (bean != null) {
            mView?.showAndroidData(bean)
            if (bean.error == "true") {
                mView?.showErrorMsg()
            }
        } else {
            mView?.showErrorMsg()
        }
    }

}

BaseActivity

BaseActivity除了日常的getLayoutId() initView() initData() initEvent()四个抽象方法之外,主要还是封装了通用的进度条的显示和隐藏,P层和V层的绑定和解绑。

MVP-BaseActivity.png
  1. 通过实现IBaseView接口,把里面的方法进行重写,调用showLoadingView()hideLoadingView()方法。

  2. 通过泛型来实现P层的引用,然后通过abstract fun getPresenter(): T来得到具体的Presenter,这样就可以在onCreate()方法里面对P和V进行绑定,在onDestory()方法里对P层引用的View进行释放。

具体代码如下:

package com.taonce.kotlindemo.base

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import com.taonce.kotlindemo.R
import com.taonce.kotlindemo.ui.inter.IBaseView

abstract class BaseActivity<V, T : BasePresenter<V>> : AppCompatActivity(), IBaseView {

    private var baseLoadingView: BaseLoadingView? = null
    private var basePresenter: T? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(getLayoutId())
        basePresenter = getPresenter()
        basePresenter?.attachView(this as V)
        initLoadingView()
        initView()
        initData()
        initEvent()
    }

    abstract fun getLayoutId(): Int

    abstract fun initData()

    abstract fun initView()

    abstract fun initEvent()

    abstract fun getPresenter(): T


    override fun onResume() {
        super.onResume()
    }

    override fun onDestroy() {
        super.onDestroy()

        // 销毁dialog
        if (null != baseLoadingView && baseLoadingView!!.isShowing) {
            baseLoadingView?.dismiss()
        }
        baseLoadingView = null

        // 在activity销毁时,解绑activity和presenter
        if (basePresenter != null) {
            basePresenter?.detachView()
            basePresenter = null
        }
    }

    override fun onStop() {
        super.onStop()
    }

    override fun onPause() {
        super.onPause()
    }

    private fun initLoadingView() {
        baseLoadingView = BaseLoadingView(this, R.style.transparent_dialog)
    }

    private fun showLoadingView() {
        if (null != baseLoadingView) {
            baseLoadingView?.show()
        } else {
            initLoadingView()
            baseLoadingView?.show()
        }
    }

    private fun hideLoadingView() {
        if (null != baseLoadingView && baseLoadingView!!.isShowing) {
            baseLoadingView?.cancel()
        }
    }

    /**
     * 将显示dialog和取消dialog放在了基础类中
     */
    override fun showLoading() {
        showLoadingView()
    }

    override fun hideLoading() {
        hideLoadingView()
    }
}


网络

网络部分主要采用的是OkHttp3+Retrofit2的方式,通过OKHttp3设置公共头参、Log输出、超时连接等,Retrofit2是用来进行网络请求,最终的线程转换是通过RxJava来实现的,由于网络这块还没深入去探究,暂时只简单封装了一下,后期会在此基础上完善。具体的代码会在文末贴上链接。


整个封装就介绍到这里啦,如果大家觉得有什么不足的地方,欢迎随时交流沟通,期待你们的批评。项目已上传GitHub,地址为:GitHub


写在最后

每个人不是天生就强大,你若不努力,如何证明自己,加油!

Thank You!

--Taonce

如果你觉得这篇文章对你有所帮助,那么就动动小手指,长按下方的二维码,关注一波吧~~非常期待大家的加入

专注Kotlin知识的公众号

相关文章

  • Kotlin-MVP框架

    这段时间在写基于gank API客户端Demo的时候,尝试着封装了一把MVP,下面就来谈谈这整个过程中的一些感想。...

  • Kotlin-MVP框架搭建

    Github地址:https://github.com/cn-ljb/mvp-kotlin 该项目是本人使用Kot...

  • 在kotlin-MVP使用dagger2(v2.11+)

    这个一个简单的例子;介绍如何在Kotlin-MVP中使用dagger2(v2.11+),基本使用就不介绍了,还是跟...

  • Kotlin-MVP开源app--开眼短视频

    前言:kotlin出来也好一段时间了,大家都在熟悉kotlin,kotlin在开发android的优势是逐渐显现(...

  • Android 中常用的框架集合

    常用框架 常用框架 常用框架 常用框架 常用框架 常用框架 常用框架 UI框架 感谢以上链接博主大佬的奉献。

  • 全脑表达笔记

    左脑逻辑 6个框架:时间框架、空间框架、支点框架、钟摆框架、变焦框架、递推框架。 右脑感性 6个力量:对比力量,视...

  • thinkphp安装

    php框架 TP3.2框架 laravel框架 Yii框架 TP5.0框架 thinkphp框架简介 免费开源 T...

  • SSM 框架快速整合实例--学生查询

    一、快速准备 SSM 框架即 Spring 框架、SpringMVC 框架、MyBatis 框架,关于这几个框架的...

  • 多媒体笔记 | 框架流程

    一、整体框架 二、MediaPlayer框架 三、相机框架 四、录像框架 五、Video Camera框架 六、O...

  • 1.Mybatis-01 框架概述,Mybatis 框架快速入门

    主要内容 框架概述 Mybatis 框架快速入门 1.1 什么是框架 1.1.1 什么是框架 框架( Framew...

网友评论

  • 莫离境:感觉现在使用ViewModel更方便点
    Taonce:@莫离境 哈哈,我理解成了MVVM了,不过你说的那是组件化了,这个封装中还没有考虑过,谢谢提醒哦
    莫离境:@Taonce 不不不,我说的是 Google 推出的 Android Architecture Component 中的ViewModel ,它的主要作用就是在配置变更时数据不会被销毁,以及同一context 拿到的ViewModel是同一个,也就相当于做到了数据传递的作用。它结合 LiveData 省去了 Presenter 中调用 View 方法的那一步,当然这个操作就算不用ViewModel组件也一样可以的。
    Taonce:@莫离境 ViewModel在数据和view的绑定上确实做的不错,不过MVP目前看来还是使用最多的吧

本文标题:Kotlin-MVP框架

本文链接:https://www.haomeiwen.com/subject/vicztqtx.html