前言
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的实现和封装,待续......
网友评论