前言
之前写过一篇文章说的是如何用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模式及基类的简单封装,谢谢观看
网友评论