性能优化移动架构

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

2017-09-21  本文已影响0人  2012lc

前言

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的实现和封装,待续......

上一篇 下一篇

猜你喜欢

热点阅读