Android(Kotlin)框架MVP的簡(jiǎn)單實(shí)現(xiàn)

1.我們通常所說的MVP是什么?

M(Model)負(fù)責(zé)數(shù)據(jù)的請(qǐng)求,解析,過濾等數(shù)據(jù)操作。
V(View)負(fù)責(zé)處理UI,通常以Activity Fragment的形式出現(xiàn)。
P(Presenter)View Model中間件,交互的橋梁。

2.MVP的優(yōu)點(diǎn)

分離了UI邏輯和業(yè)務(wù)邏輯,降低了耦合。
Activity只處理UI相關(guān)操作,代碼變得更加簡(jiǎn)潔。
UI邏輯和業(yè)務(wù)邏輯抽象到接口中,方便閱讀及維護(hù)。
把業(yè)務(wù)邏輯抽到Presenter中去,避免復(fù)雜業(yè)務(wù)邏輯造成的內(nèi)存泄漏。

3.Base基礎(chǔ)類

BaseView

/**
* Description:View的基類
*
* 負(fù)責(zé)處理UI,通常以Activity Fragment的形式出現(xiàn)。
*
* Time:2021/8/8-16:13
* Author:我叫PlusPlus
*/
interface BaseView {
/**
    * 結(jié)束當(dāng)前Activity等
    */
    fun finish()
}

BasePresenter

/**
 * Description: Presenter的基類
 *
 * View Model中間件,交互的橋梁。
 *
 * Time:2021/8/8-16:12
 * Author:我叫PlusPlus
 */
abstract class BasePresenter<V : BaseView> {

    private var v: V? = null

    fun getView(): V {
        return v!!
    }

    fun attachView(view: V?) {
        this.v = view
    }

    fun detachView() {
        v = null
    }
}

BaseActivity

/**
 * Description:Activity基類
 *
 * Time:2021/8/8-16:12
 * Author:我叫PlusPlus
 */
abstract class BaseActivity<V : BaseView, P : BasePresenter<V>> : Activity() {
    /**
     * 定義泛型 View
     */
    private var view: V? = null

    /**
     * 定義泛型 Presenter
     */
    private var presenter: P ? = null

    /**
     * 可以被子類使用的Presenter
     */
    protected var currentPresenter :  P ? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //判斷當(dāng)前
        if (view == null) {
            view = createView()
        }
        if (presenter == null) {
            presenter = createPresenter()
        }
        //綁定view
        presenter?.attachView(view)
        currentPresenter = presenter
    }

    override fun onDestroy() {
        super.onDestroy()
        //剝離view
        presenter?.detachView()
    }

    /**
     * 創(chuàng)建View的抽象方法
     */
    abstract fun createView(): V
    /**
     * 創(chuàng)建Presenter的抽象方法
     */
    abstract fun createPresenter(): P
}

4.實(shí)現(xiàn)類,就以登錄(Login)為例

LoginActivity

/**
 * Description:登錄
 *
 * Time:2021/8/8-16:15
 * Author:我叫PlusPlus
 */
class LoginActivity : BaseActivity<LoginView, LoginPresenter>(), LoginView {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        httpBtn.setOnClickListener {
             currentPresenter?.sendHttpRequest()
        }
    }

    override fun createView(): LoginView {
       return this
    }

    override fun createPresenter(): LoginPresenter {
        return LoginPresenter()
    }

    override fun onLoginSuccess(message: String) {
        runOnUiThread {
            Toast.makeText(this, "請(qǐng)求成功 : $message",Toast.LENGTH_SHORT).show()
        }

    }

    override fun onLoginFailed(message: String) {
         runOnUiThread {
             Toast.makeText(this,"請(qǐng)求失敗 : $message",Toast.LENGTH_SHORT).show()
         }
    }
}

LoginModel

/**
 * Description:登錄Model
 *
 * 負(fù)責(zé)數(shù)據(jù)的請(qǐng)求,解析,過濾等數(shù)據(jù)操作
 * Time:2021/8/8-17:15
 * Author:我叫PlusPlus
 */
class LoginModel {
    /**
     * 請(qǐng)求成功監(jiān)聽
     */
    var httpSuccess: ((String) -> Unit)? = null

    /**
     * 請(qǐng)求失敗監(jiān)聽
     */
    var httpFailed: ((String) -> Unit)? = null

    fun sendHttpRequest(request: String) {
        val okHttpClient: OkHttpClient = OkHttpClient()
        val httpRequest = Request.Builder()
            .url(request) //添加的url
            .get() // get請(qǐng)求
            .build()
        val call: Call = okHttpClient.newCall(httpRequest)
        call.enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                httpFailed?.invoke(e.message.toString())
            }

            override fun onResponse(call: Call, response: Response) {
                httpSuccess?.invoke(response.body().toString())
            }
        })
    }
}

LoginPresenter

/**
 * Description:登錄的Presenter
 *
 * Time:2021/8/8-16:19
 * Author:我叫PlusPlus
 */
class LoginPresenter : BasePresenter<LoginView>() {

    /**
     * 懶加載 LoginModel
     */
    private val loginModel by lazy {
        LoginModel()
    }

    fun sendHttpRequest() {
        //loginModel回調(diào)到當(dāng)前Presenter,Presenter在回調(diào)到Activity
        loginModel.httpSuccess = {
            getView().onLoginSuccess(it)
        }
        loginModel.httpFailed = {
           getView().onLoginFailed(it)
        }
        loginModel.sendHttpRequest("http://wwww.baidu.com")
    }
}

LoginView

/**
 * Description:登錄View
 *
 * Time:2021/8/8-16:17
 * Author:我叫PlusPlus
 */
interface LoginView : BaseView {
    /**
     * 登錄成功回調(diào)
     */
    fun onLoginSuccess(message: String)
    /**
     * 登錄失敗回調(diào)
     */
    fun onLoginFailed(message: String)
}

總結(jié)

當(dāng)前MVP只是將最基本的框架和基類搭建出來,可以根據(jù)自己的項(xiàng)目的需要做對(duì)應(yīng)的修改。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容