美文网首页性能优化移动架构
Kotlin+Retrofit+RxJava+MVP封装(一)

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

作者: 2012lc | 来源:发表于2017-09-21 09:55 被阅读0次

    前言

    kotlin系统学习:http://www.jianshu.com/u/5509a21c1623
    retrofit学习:http://www.jianshu.com/p/3e13e5d34531
    rxjava学习:http://www.jianshu.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:处理业务逻辑
    view:展示视图
    presenter:中间人(绑定view和model)
    那么view和presenter之间是通过接口进行交互,这样能够降低耦合,方便进行单元测试。

    实现一个简单的登录demo

    我们先看一下目录结构:

    目录结构.png

    需要导入的第三方库:

       /*网络依赖*/
        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实现

    使用kotlin创建interface和activity

    创建activity和interface.png 登录界面.png

    如大多数登录界面所示,在登录时我们需要输入用户名和密码,以及点击登录按钮过后的一个监听回调,所以在写接口时我们需要三样东西:

    interface LoginView :BaseView{
    
        fun getUserName(): String//获取用户名
        fun getPassWord(): String//获取密码
        fun LoginSuccess(baseBean: BaseBean)//登录成功
        fun LoginFailed(baseBean: BaseBean)//登录失败
    
    }
    

    我们在activity中实现以上接口,对界面做出相应操作:

    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()
    
        }
    

    以上,我们创建完了对应的activity以及接口,相应的我们需要去处理逻辑的Model以及把model和view相关联的presenter。

    Model实现

    因为model是逻辑处理的,所以在登录时需要做出登录的逻辑操作和登录过后的返回动作,

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

    然后我们写好相对应的实现类,实现上面的接口,进行一个具体的操作:

    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?) {
    
        }
    //声明监听接口
        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)
            }
        }
    //需要传入的参数
        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>{
    
    //需要传入的参数
        var mParams:HashMap<String,String>?=HashMap()
    //进行数据请求
        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都已经实现了,那么就得通过presenter来进行绑定、交互了。

    Presenter实现

    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的一部分差不多就这些了,小结一哈:
    1.首先对应功能需求实现view就对应的activity;
    2.对应逻辑需求实现Model和ModelImpl;
    3.通过各自接口,实现presenter,实现model和view的交互。

    Retrofit+RxJava实现

    //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)
                        }
                    })
    

    小结:
    1.创建一个Retrofit;
    2.创建接口,通过Retrofit获取实例;
    3.结合Rxjava,实现线程切换,逻辑更加流畅。

    总结

    在这篇文章中,是对Kotlin+Retrofit+RxJava+MVP的一个简单实现,如果需要补基础的话可以借鉴前言的博客或者简书。这篇简书没有相对应的源码,因为后续会在这篇文章的基础上对源码进行封装以及Recyclerview的实现和封装,待续......

    相关文章

      网友评论

        本文标题:Kotlin+Retrofit+RxJava+MVP封装(一)

        本文链接:https://www.haomeiwen.com/subject/cwsosxtx.html