Kotlin+Retrofit+RxJava+MVP封裝(一)

前言

kotlin系統(tǒng)學習:http://www.reibang.com/u/5509a21c1623
retrofit學習:http://www.reibang.com/p/3e13e5d34531
rxjava學習:http://www.reibang.com/p/464fa025229e
mvp學習:http://blog.csdn.net/lmj623565791/article/details/46596109
Kotlin+Retrofit+RxJava+MVP封裝(二)
Kotlin+Retrofit+RxJava+MVP封裝(三)

MVP簡介

mvp和mvc.png

我們可以對mvp進行一個簡單的理解拖吼,mvp分別為:
model:處理業(yè)務邏輯
view:展示視圖
presenter:中間人(綁定view和model)
那么view和presenter之間是通過接口進行交互丽啡,這樣能夠降低耦合,方便進行單元測試血筑。

實現(xiàn)一個簡單的登錄demo

我們先看一下目錄結(jié)構(gòu):

目錄結(jié)構(gòu).png

需要導入的第三方庫:

   /*網(wǎng)絡依賴*/
    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.1.0'
    compile 'com.squareup.okhttp3:okhttp:3.2.0'
    compile 'com.squareup.okhttp3:logging-interceptor:3.2.0'
    compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
   /*rxjava*/
    compile 'io.reactivex:rxandroid:1.1.0'
    compile 'io.reactivex:rxjava:1.1.0'
   /*圖片處理(glide)*/
    compile 'com.github.bumptech.glide:glide:3.7.0'

view interface及activity實現(xiàn)

使用kotlin創(chuàng)建interface和activity

創(chuàng)建activity和interface.png
登錄界面.png

如大多數(shù)登錄界面所示婉支,在登錄時我們需要輸入用戶名和密碼春宣,以及點擊登錄按鈕過后的一個監(jiān)聽回調(diào)纫骑,所以在寫接口時我們需要三樣東西:

interface LoginView :BaseView{

    fun getUserName(): String//獲取用戶名
    fun getPassWord(): String//獲取密碼
    fun LoginSuccess(baseBean: BaseBean)//登錄成功
    fun LoginFailed(baseBean: BaseBean)//登錄失敗

}

我們在activity中實現(xiàn)以上接口,對界面做出相應操作:

override fun getUserName(): String {
        return "test"
    }

    override fun getPassWord(): String {
        return "111111"
    }

    override fun LoginSuccess(baseBean: BaseBean) {
        LoadingDis()
        openActivity(MoneyDetailActivity::class.java)
        Toast.makeText(this,"成功"+baseBean.message,Toast.LENGTH_SHORT).show()

    }

    override fun LoginFailed(baseBean: BaseBean) {
        LoadingDis()
        Toast.makeText(this,"失敗"+baseBean.message,Toast.LENGTH_SHORT).show()

    }

以上澄暮,我們創(chuàng)建完了對應的activity以及接口名段,相應的我們需要去處理邏輯的Model以及把model和view相關聯(lián)的presenter。

Model實現(xiàn)

因為model是邏輯處理的赏寇,所以在登錄時需要做出登錄的邏輯操作和登錄過后的返回動作吉嫩,

interface LoginModel {
    //登錄
    fun Login(username:String,password:String)
    / /登錄完成過后的接口
    fun LoadComplete(onLoginListener: OnLoginListener)
    interface OnLoginListener{
        fun LoginSuccess(baseBean: BaseBean)
        fun LoginFailed(baseBean: BaseBean)
    }
}

然后我們寫好相對應的實現(xiàn)類,實現(xiàn)上面的接口嗅定,進行一個具體的操作:

class LoginModeImpl: LoginModel, BaseModel<BaseBean>() {
//取到RetrofitManager中的service
    override fun ServiceParams(params: HashMap<String, String>): Observable<BaseBean> {
        return RetrofitManager.builder().service!!.getRegisterList(params)
    }


    //var mOnLoginListenr:LoginPresenter.onLoginListener?=null
    var mOnLoginListener: LoginModel.OnLoginListener?=null
    var mUserName:String?=null
    var mPassWord:String?=null

//失敗過后的操作
    override fun FailedOperation(e: Throwable?) {

    }
//聲明監(jiān)聽接口
    override fun LoadComplete(onLoginListener: LoginModel.OnLoginListener) {
        if(mOnLoginListener==null){
            mOnLoginListener=onLoginListener
        }
    }

//登錄成功過后的操作
    override fun SuccessOperation(o: BaseBean) {
       // val message = o.message
        if(o.success){
            mOnLoginListener!!.LoginSuccess(o)

        }else{
            mOnLoginListener!!.LoginFailed(o)
        }
    }
//需要傳入的參數(shù)
    override fun Params(): HashMap<String, String>? {
        ClearHashMap()
        mParams!!.put("username",mUserName!!)
        mParams!!.put("password",mPassWord!!)
        return mParams
    }

//進行的登錄操作
    override fun Login(username: String, password: String) {
        mUserName=username
        mPassWord=password
        PostParams()

    }
}

因為我對Model進行了一個簡單的封裝自娩,可能有點看不懂,我把basemodel的代碼也貼出來渠退,這樣便于理解:

abstract class BaseModel <T:BaseBean>{

//需要傳入的參數(shù)
    var mParams:HashMap<String,String>?=HashMap()
//進行數(shù)據(jù)請求
    open fun PostParams(){
        ServiceParams(Params()!!)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe (object : Subscriber<BaseBean>() {
                    override fun onCompleted() {
                        Completed()
                    }

                    override fun onError(e: Throwable?) {
                        FailedOperation(e)
                    }

                    override fun onNext(o: BaseBean) {
                       // val message = o.message
                        //mOnLoginListenr?.LoginSuccess()
                        SuccessOperation(o)
                    }
                })
    }

    open fun Completed() {

    }

    abstract fun FailedOperation(e: Throwable?)



    abstract fun SuccessOperation(o: BaseBean)


    abstract fun Params(): HashMap<String, String>?
//得到rxjava中的Observable
    abstract fun ServiceParams(params: HashMap<String, String>): Observable<T>

    open fun ClearHashMap(){
        if (mParams!!.size>0)
            mParams!!.clear()
    }


}

到此忙迁,我們的view和model都已經(jīng)實現(xiàn)了,那么就得通過presenter來進行綁定碎乃、交互了姊扔。

Presenter實現(xiàn)

presenter來綁定view和model,那么顯然梅誓,presenter將持有view和model的一個對象恰梢,比較簡單佛南,直接貼代碼:

class LoginPresenterxx(val loginView: LoginView): BasePresenter<LoginView>() {

    var loginmode:LoginModel?=null

    init {
        loginmode= LoginModeImpl()
    }

    fun Login(username: String, password: String){
        loginmode!!.Login(username,password)

        loginmode!!.LoadComplete(object : LoginModel.OnLoginListener {
            override fun LoginSuccess(baseBean: BaseBean) {
                loginView.LoginSuccess(baseBean)
            }

            override fun LoginFailed(baseBean: BaseBean) {
                loginView.LoginFailed(baseBean)
            }
        })
    }
}

至此,關于mvp的一部分差不多就這些了嵌言,小結(jié)一哈:
1.首先對應功能需求實現(xiàn)view就對應的activity嗅回;
2.對應邏輯需求實現(xiàn)Model和ModelImpl;
3.通過各自接口,實現(xiàn)presenter摧茴,實現(xiàn)model和view的交互绵载。

Retrofit+RxJava實現(xiàn)

//retrofit的一個初始化
initOkHttpclient()
        var retrofit = Retrofit.Builder()
                .baseUrl(Constants.BASE_URL)
                .client(mOkHttpClient)
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build()

        service = retrofit.create(RetrofitService::class.java)

//對okhttp的一個初始化
    fun initOkHttpclient() {
        //log信息攔截器
        val interceptor = HttpLoggingInterceptor()
   
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        if (mOkHttpClient == null) {
            mOkHttpClient = OkHttpClient.Builder()
      
                    .retryOnConnectionFailure(true)
                    .addNetworkInterceptor(this)
                    .addInterceptor(this)
                    .connectTimeout(15, TimeUnit.SECONDS)
                    .readTimeout(10000L, TimeUnit.MILLISECONDS)//讀操作超時時間
                    .cookieJar(CookiesManager())//設置長久存在的cookie
                    .build()
        }
    }
//定義的接口類
interface RetrofitService {

    //登錄
    @FormUrlEncoded
    @POST("/app/common/login.html")
    fun getRegisterList(@FieldMap params: HashMap<String, String>): Observable<BaseBean>
}
//通過rxjava處理線程切換
ServiceParams(Params()!!)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe (object : Subscriber<BaseBean>() {
                    override fun onCompleted() {
                        Completed()
                    }

                    override fun onError(e: Throwable?) {
                        FailedOperation(e)
                    }

                    override fun onNext(o: BaseBean) {
                       // val message = o.message
                        //mOnLoginListenr?.LoginSuccess()
                        SuccessOperation(o)
                    }
                })

小結(jié):
1.創(chuàng)建一個Retrofit;
2.創(chuàng)建接口,通過Retrofit獲取實例苛白;
3.結(jié)合Rxjava娃豹,實現(xiàn)線程切換,邏輯更加流暢购裙。

總結(jié)

在這篇文章中懂版,是對Kotlin+Retrofit+RxJava+MVP的一個簡單實現(xiàn),如果需要補基礎的話可以借鑒前言的博客或者簡書缓窜。這篇簡書沒有相對應的源碼定续,因為后續(xù)會在這篇文章的基礎上對源碼進行封裝以及Recyclerview的實現(xiàn)和封裝,待續(xù)......

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末禾锤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子摹察,更是在濱河造成了極大的恐慌恩掷,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件供嚎,死亡現(xiàn)場離奇詭異黄娘,居然都是意外死亡,警方通過查閱死者的電腦和手機克滴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門逼争,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人劝赔,你說我怎么就攤上這事誓焦。” “怎么了着帽?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵杂伟,是天一觀的道長。 經(jīng)常有香客問我仍翰,道長赫粥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任予借,我火速辦了婚禮越平,結(jié)果婚禮上频蛔,老公的妹妹穿的比我還像新娘。我一直安慰自己秦叛,他們只是感情好帽驯,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著书闸,像睡著了一般尼变。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浆劲,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天嫌术,我揣著相機與錄音,去河邊找鬼牌借。 笑死度气,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的膨报。 我是一名探鬼主播磷籍,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼现柠!你這毒婦竟也來了院领?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤够吩,失蹤者是張志新(化名)和其女友劉穎比然,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體周循,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡强法,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了湾笛。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饮怯。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖嚎研,靈堂內(nèi)的尸體忽然破棺而出蓖墅,到底是詐尸還是另有隱情,我是刑警寧澤嘉赎,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布置媳,位于F島的核電站,受9級特大地震影響公条,放射性物質(zhì)發(fā)生泄漏拇囊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一靶橱、第九天 我趴在偏房一處隱蔽的房頂上張望寥袭。 院中可真熱鬧路捧,春花似錦、人聲如沸传黄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽膘掰。三九已至章姓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間识埋,已是汗流浹背凡伊。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留窒舟,地道東北人系忙。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像惠豺,于是被迫代替她去往敵國和親银还。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容