1. 程式人生 > 其它 >Kotlin+Retrofit+Okhttp+MVP架構的搭建以及示例程式碼

Kotlin+Retrofit+Okhttp+MVP架構的搭建以及示例程式碼

技術標籤:Androidandroidmvpkotlin

本文地址:https://blog.csdn.net/qq_40785165/article/details/113200783,轉載需附上此地址

大家好,我是小黑,一個還沒禿頭的程式設計師~~~

最近是真的忙,忙到不想寫部落格,但是還是那句老話--既然選擇了遠方,便只顧風雨兼程。

今天的內容是Kotlin+Retorfit+Okhttp+MVP架構的搭建,由於Kotlin+Retrofit+Okhttp的搭建我之前的部落格中已經有案例了,有需要的小夥伴可以跳轉至文章地址檢視,所以本文的重點在於MVP架構的程式碼介紹

本文章涉及的Demo地址:專案地址

,裡面有標題中涉及到的所有知識點,有需要的小夥伴可以去看看專案原始碼,Demo的功能為登入成功後可進行檢視資料列表,也可退出登入,Demo的執行效果以及專案目錄結構如下所示

我之前也有寫過Kotlin+MVC的部落格,感興趣的小夥伴可以去文章地址檢視原文

MVC中View層指的是xml程式碼或者Java程式碼寫的自定義view,Control層指的是Activity/Fragment,View層可以直接與Model進行互動,更新UI的工作都是在Control層執行,但是MVP架構中View層指的就是Activity/Fragment,View層只能通過Presenter層和Model進行互動,或者說Presenter層是作為View與Model的橋樑,View層通過Presenter層呼叫Model層的介面進行資料處理,Model層執行結束將結果回撥通知Presenter層,Presenter層通過回撥通知View層進行UI更新,從程式碼而言,MVC更容易易懂,但是程式碼容易臃腫,MVP容易產生過多的類和介面,但是分工明確,易於拓展。以上是我個人的理解,若有不同見解,歡迎底下評論區多多指教!

正文開始,以下以效果中的登入功能為例(退出以及列表功能程式碼請閱讀專案原始碼),介面呼叫wanandroid的開放Api

(一)View層程式碼

activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="賬號:" />

        <EditText
            android:id="@+id/et_account"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="請輸入賬號"
            android:inputType="text"
            android:text="" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="密碼:" />

        <EditText
            android:id="@+id/et_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="請輸入密碼"
            android:inputType="text"
            android:text="" />
    </LinearLayout>

    <TextView
        android:id="@+id/tv_login"
        android:layout_width="@dimen/dp_40"
        android:layout_height="@dimen/dp_40"
        android:layout_gravity="center"
        android:layout_marginTop="@dimen/dp_40"
        android:background="#c0c0c0"
        android:gravity="center"
        android:text="登入"
        android:textColor="#000" />

</LinearLayout>

LoginActivity.kt程式碼如下,activity繼承了LoginView介面,實現更新UI方法,易於通過Presenter與Model進行互動並接受回撥

class LoginActivity : AppCompatActivity(), LoginView {
    private val loginModel: LoginModel by lazy {
        LoginModel()
    }
    private val loginPresenterImpl: ILoginPresenter by lazy {
        LoginPresenterImpl(this, loginModel)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_login)
        initListener()
    }

    private fun initListener() {
        tv_login.setOnClickListener {
            loginPresenterImpl.login(et_account.text.toString(), et_password.text.toString())
        }
    }

    override fun showLoading() {
        Toast.makeText(this, "登入載入中", Toast.LENGTH_SHORT).show()
    }

    override fun hideLoading() {
        Toast.makeText(this, "登入載入結束", Toast.LENGTH_SHORT).show()
    }

    override fun loginSuccess() {
        Toast.makeText(this, "登入成功", Toast.LENGTH_SHORT).show()
        var intent = Intent(this, MainActivity::class.java)
        startActivity(intent)
        finish()
    }

    override fun loginFail(msg: String?) {
        Toast.makeText(this, "登入失敗", Toast.LENGTH_SHORT).show()
    }
}

LoginView.kt程式碼如下,定義了各種需要更新UI的函式,用於P層呼叫這些函式進行通知UI更新

/**
 * 用來View層更新UI的介面
 */
interface LoginView {
    /**
     * 顯示載入中提示
     */
    fun showLoading()

    /**
     * 隱藏載入中提示
     */
    fun hideLoading()

    /**
     * 登陸成功的UI更新
     */
    fun loginSuccess()

    /**
     * 登入失敗的UI更新
     */
    fun loginFail(msg: String?)

}

(二)Presenter層程式碼

ILoginPresenter.kt程式碼如下,定義了Presenter層需要呼叫的方法,在該方法裡進行邏輯處理或者呼叫Model,也方便拓展

/**
 * P層作為view與model的媒介,需要的介面方法
 */
interface ILoginPresenter {
    fun login(account: String, password: String)
}

LoginPresenterImpl.kt程式碼如下,實現了ILoginPresenter中的介面方法,並實現Model層約定的回撥方法,呼叫Model層進行資料處理,Presenter層作為中介軟體,所以需要持有View層與Model層的物件

/**
 * 作為媒介聯絡view與model,view和model各司其職互不干擾,等待model返回回撥,present再去通知view層進行UI更新
 */
class LoginPresenterImpl(loginView: LoginView, iLoginModel: ILoginModel) : ILoginPresenter,
    LoginListener {
    private var loginView: LoginView? = null
    private var loginModel: ILoginModel? = null

    init {
        this.loginModel = iLoginModel
        this.loginView = loginView
    }

    override fun login(account: String, password: String) {
        loginView?.showLoading()
        loginModel?.login(account, password, this)
    }

    override fun loginSuccess() {
        loginView?.hideLoading()
        loginView?.loginSuccess()
    }

    override fun loginFail(msg: String?) {
        loginView?.hideLoading()
        loginView?.loginFail(msg)
    }
}

(三)Model層程式碼

ILoginModel.kt程式碼如下,也是一個介面,定義資料處理函式名

/**
 * 處理資料的介面方法
 */
interface ILoginModel {
    fun login(account: String, password: String, loginListener: LoginListener)
}

LoginModel.kt程式碼如下,實現介面函式,使用retrofit+okhttp進行登入請求,並且將結果通過回撥通知Presenter層,retrofit程式碼這裡就不貼出來了,可以前往專案地址檢視專案原始碼

class LoginModel : ILoginModel {
    override fun login(account: String, password: String, loginListener: LoginListener) {
        HttpHelper.getApi()?.login(account, password)
            ?.enqueue(object : SingleCallback<Result<UserBean>>() {
                override fun onSuccess(response: Result<UserBean>) {
                    if ("0".equals(response.errorCode)) {
                        loginListener.loginSuccess()
                    } else {
                        loginListener.loginFail(response.errorMsg)
                    }
                }


            })
    }
}

到此為止,MVP架構就搭建成功了,因為自己本身也是個學習者,所以文章不能起到太大教學作用,目前只能作為記錄以及筆記使用,所以文章中有不妥之處歡迎大家評論區指出來,大家共同討論,共同進步!謝謝大家的支援與閱讀!