前言
之前寫過一篇文章說的是如何用java實現(xiàn)mvp模式
Android MVP模式 簡單入門實踐
現(xiàn)在不是用的Kotlin比較多嘛,所以來做下用kotlin實現(xiàn)MVP模式的筆記
而且之前的也只是簡單應(yīng)用母谎,實際開發(fā)它是存在著設(shè)計問題的,如重復(fù)代碼渤闷、內(nèi)存泄漏
正文
這次的mvp實現(xiàn)和之前用java實現(xiàn)的一模一樣
所以一些解釋就不在這里重復(fù)了
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 = "假裝自己是從服務(wù)器獲取到的數(shù)據(jù)"
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
}
}
存在問題
我們不難發(fā)現(xiàn)這樣實現(xiàn)的MVP需要重復(fù)聲明mPresenter喻频、mView
而且mPresenter是一直持有對mView的引用的(在oncreat里面綁定卻沒有解綁)
解決方案
所以我們需要寫一個baseActivity托酸、basePresenter來避免重復(fù)聲明mPresenter和mView
為了避免mPresenter導(dǎo)致的內(nèi)存泄漏
還需要attachView()來獲取view的實例在onCreat()里
和detachView()來釋放view對象的引用讓GC回收內(nèi)存
BaseContract
attachView()和detachView()是重復(fù)的業(yè)務(wù)邏輯,所以將其放到這里
interface BaseContract {
interface BaseView{
}
interface BasePresenter<in T>{
fun attachView(view: T)
fun detachView()
}
}
BasePresenter
在kotlin里需要用open關(guān)鍵字聲明該類是可繼承的
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() 相關(guān)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 = "假裝自己是從服務(wù)器獲取到的數(shù)據(jù)"
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
}
}
結(jié)語
以上就是用kotlin實現(xiàn)的mvp模式及基類的簡單封裝不跟,謝謝觀看