美文网首页
Kotlin Android MVP设计模式及基类的实现

Kotlin Android MVP设计模式及基类的实现

作者: 水天滑稽天照八野滑稽石 | 来源:发表于2019-02-19 19:38 被阅读0次

    前言

    之前写过一篇文章说的是如何用java实现mvp模式
    Android MVP模式 简单入门实践
    现在不是用的Kotlin比较多嘛,所以来做下用kotlin实现MVP模式的笔记
    而且之前的也只是简单应用,实际开发它是存在着设计问题的,如重复代码、内存泄漏

    正文

    这次的mvp实现和之前用java实现的一模一样
    所以一些解释就不在这里重复了
    View+Contract+Presenter


    MVPContract

    interface MVPContract {
    
        interface View{
            fun onDataLoad(str: String)
        }
    
        interface Presenter{
            fun dataLoad()
        }
    }
    

    MVPPresenter

    class MVPPresenter constructor(var mView: MVPContract.View) : MVPContract.Presenter{
    
        override fun dataLoad() {
            val str = "假装自己是从服务器获取到的数据"
            Thread(Runnable {
                try {
                    Thread.sleep(2000)
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
            }).start()
            mView.onDataLoad(str)
        }
    
    }
    

    MVPActivity

    class MVPActivity : AppCompatActivity(), MVPContract.View {
    
        private var mPresenter: MVPPresenter? = null
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_mvp)
            mPresenter = MVPPresenter(this)
            textView.setOnClickListener{ mPresenter!!.dataLoad()}
        }
    
        override fun onDataLoad(str: String) {
            textView.text = str
        }
    }
    

    存在问题

    我们不难发现这样实现的MVP需要重复声明mPresenter、mView
    而且mPresenter是一直持有对mView的引用的(在oncreat里面绑定却没有解绑)

    解决方案

    所以我们需要写一个baseActivity、basePresenter来避免重复声明mPresenter和mView
    为了避免mPresenter导致的内存泄漏
    还需要attachView()来获取view的实例在onCreat()里
    和detachView()来释放view对象的引用让GC回收内存

    BaseContract

    attachView()和detachView()是重复的业务逻辑,所以将其放到这里

    interface BaseContract {
    
        interface BaseView{
    
        }
    
        interface BasePresenter<in T>{
            fun attachView(view: T)
            fun detachView()
        }
    
    }
    

    BasePresenter

    在kotlin里需要用open关键字声明该类是可继承的

    open class BasePresenter<T : BaseContract.BaseView> : BaseContract.BasePresenter<T> {
    
        protected var mView: T? = null
    
        override fun attachView(view: T) {
            this.mView = view
        }
    
        override fun detachView() {
            this.mView = null
        }
    }
    

    BaseActivity

    getLayoutId() 视图绑定
    initPresenter() 初始presenter
    configView() 相关view的事件

    abstract class BaseActivity <in V: BaseContract.BaseView,P :BaseContract.BasePresenter<V>> : AppCompatActivity(){
    
        protected var mPresenter: P? = null
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            mPresenter = initPresenter()
            mPresenter!!.attachView(this as V)
            setContentView(getLayoutId())
            configView()
        }
    
        override fun onDestroy() {
            super.onDestroy()
            mPresenter!!.detachView()
        }
    
        protected abstract fun getLayoutId(): Int
        protected abstract fun initPresenter(): P
        protected abstract fun configView()
    }
    

    MainContract

    需要注意的是Presenter绑定的view为该契约类生声明的view

    interface MainContract {
    
        interface View: BaseContract.BaseView{
            fun onLoadData(str: String)
        }
    
        interface Presenter : BaseContract.BasePresenter<View>{
            fun loadData()
        }
    }
    

    MainPresenter

    class MainPresenter : BasePresenter<MainContract.View>(),MainContract.Presenter{
    
        override fun loadData() {
            val str = "假装自己是从服务器获取到的数据"
            Thread(Runnable {
                try {
                    Thread.sleep(2000)
                } catch (e: InterruptedException) {
                    e.printStackTrace()
                }
            }).start()
            mView!!.onLoadData(str)
        }
    
    }
    

    MainActivity

    class MainActivity : BaseActivity<MainContract.View,MainContract.Presenter>(),MainContract.View {
    
    
        override fun getLayoutId(): Int = R.layout.activity_main
    
        override fun initPresenter(): MainContract.Presenter = MainPresenter()
    
        override fun configView() {
            text.setOnClickListener{ mPresenter!!.loadData() }
        }
    
        override fun onLoadData(str: String) {
            text.text = str
        }
    }
    

    结语

    以上就是用kotlin实现的mvp模式及基类的简单封装,谢谢观看

    相关文章

      网友评论

          本文标题:Kotlin Android MVP设计模式及基类的实现

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