如题,采用MVP的框架模式,使用Kotlin编写实现了基础的登录和注册功能,包括一些回调的响应,效果图如下:
首先看下使用MVP的项目部分结构:
PS:如果还不了解MVP模式的同学可以看这篇或者自行搜索:https://blog.csdn.net/chunqiuwei/article/details/80460108
个人感觉MVP模式的好处很多,一点就是在抽离接口的时候能够合理的梳理业务的功能点,后期方便维护和测试等等。采用MVP模式的登录逻辑架构图大概如下,还是很明显能看出MVC和MVP的区别:
先梳理一下View层需要什么抽象接口,按照一般登录的逻辑来,LoginView 抽离 登录成功 和 登录失败 两个接口,代码如下:
LoginView.kt
package wanandroid.xuboyu.com.wanandroid.view
import wanandroid.xuboyu.com.wanandroid.bean.LoginResponse
/**
* use:登录界面抽离接口
* author: XuBoYu
**/
interface LoginView {
/**
* 登录成功
* @param result
*/
fun loginSuccess(result: LoginResponse)
/**
* 登录失败返回失败信息(可为空)
* @param errorMsg
*/
fun loginFailed(errorMsg: String?)
}
注册部分按照注册成功和注册失败两个接口进行处理:
RegisterView.kt
package wanandroid.xuboyu.com.wanandroid.view
import wanandroid.xuboyu.com.wanandroid.bean.LoginResponse
/**
* use:注册界面接口抽离
* author: XuBoYu
**/
interface RegisterView {
/**
* 注册成功
* @param result
*/
fun registerSuccess(result: LoginResponse)
/**
* 注册失败
* @param errorMsg
*/
fun registerFailed(errorMsg: String?)
}
接下来在 Model 层的相关业务逻辑处理回调,登录和注册部分都只需要处理成功和失败的回调,所以回调按照下面处理:
package wanandroid.xuboyu.com.wanandroid.presenter
import wanandroid.xuboyu.com.wanandroid.bean.LoginResponse
/**
* use:回调处理
* author: XuBoYu
**/
interface HomePresenter {
/**
* login 监听接口
*/
interface OnLoginListener {
/**
* 登录
* @param username username
* @param password password
*/
fun loginWanAndroid(username: String, password: String)
/**
* 登录成功
* @param result LoginResponse
*/
fun loginSuccess(result: LoginResponse)
/**
* 登录失败
* @param errorMessage error message
*/
fun loginFailed(errorMessage: String?)
}
/**
* register 监听接口
*/
interface OnRegisterListener {
/**
* 注册
* @param username username
* @param password password
* @param repassword repassword
*/
fun registerWanAndroid(username: String, password: String, repassword: String)
/**
* 注册成功
* @param result LoginResponse
*/
fun registerSuccess(result: LoginResponse)
/**
* 注册失败
* @param errorMessage error message
*/
fun registerFailed(errorMessage: String?)
}
}
然后是分别在登录和注册的Presenter中去处理实现这些接口:
LoginPresenter:
package wanandroid.xuboyu.com.wanandroid.presenter
import wanandroid.xuboyu.com.wanandroid.bean.LoginResponse
import wanandroid.xuboyu.com.wanandroid.model.HomeModel
import wanandroid.xuboyu.com.wanandroid.model.HomeModelImpl
import wanandroid.xuboyu.com.wanandroid.view.LoginView
import kotlin.math.log
/**
* use:登录presenter接口
* author: XuBoYu
**/
class LoginPresenterImpl(private val loginView: LoginView) : HomePresenter.OnLoginListener{
private val homeModel: HomeModel = HomeModelImpl()
override fun loginWanAndroid(username: String, password: String) {
homeModel.loginWanAndroid(this,username,password)
}
override fun loginSuccess(result: LoginResponse) {
if (result.errorCode != 0) {
loginView.loginFailed(result.errorMsg)
} else {
loginView.loginSuccess(result)
// loginView.loginRegisterAfter(result)
}
}
override fun loginFailed(errorMessage: String?) {
loginView.loginFailed(errorMessage)
}
}
RegisterPresenter:
package wanandroid.xuboyu.com.wanandroid.presenter
import wanandroid.xuboyu.com.wanandroid.bean.LoginResponse
import wanandroid.xuboyu.com.wanandroid.loge
import wanandroid.xuboyu.com.wanandroid.model.HomeModel
import wanandroid.xuboyu.com.wanandroid.model.HomeModelImpl
import wanandroid.xuboyu.com.wanandroid.view.RegisterView
/**
* use:注册presenter接口
* author: XuBoYu
**/
class RegisterPresenterImpl(private val registerView: RegisterView) : HomePresenter.OnRegisterListener {
private val homeModel: HomeModel = HomeModelImpl()
override fun registerWanAndroid(username: String, password: String, repassword: String) {
homeModel.registerWanAndroid(this, username, password, repassword)
}
override fun registerSuccess(result: LoginResponse) {
if (result.errorCode != 0) {
registerView.registerFailed(result.errorMsg)
} else {
registerView.registerSuccess(result)
}
}
override fun registerFailed(errorMessage: String?) {
registerView.registerFailed(errorMessage)
}
}
最后是在model层中去完成相关的IO操作,并根据结果回调不用的view:
package wanandroid.xuboyu.com.wanandroid.model
import kotlinx.coroutines.experimental.Deferred
import kotlinx.coroutines.experimental.android.UI
import kotlinx.coroutines.experimental.async
import wanandroid.xuboyu.com.wanandroid.bean.LoginResponse
import wanandroid.xuboyu.com.wanandroid.cancelByActivite
import wanandroid.xuboyu.com.wanandroid.common.Constant
import wanandroid.xuboyu.com.wanandroid.presenter.HomePresenter
import wanandroid.xuboyu.com.wanandroid.retrofit.RetrofitHelper
import wanandroid.xuboyu.com.wanandroid.tryCatch
/**
* use:首页Model实现类
* author: XuBoYu
**/
class HomeModelImpl : HomeModel{
/**
* Login async
*/
private var loginAsync: Deferred<LoginResponse>? = null
/**
* Register async
*/
private var registerAsync: Deferred<LoginResponse>? = null
override fun loginWanAndroid(
onLoginListener: HomePresenter.OnLoginListener,
username: String,
password: String) {
async(UI) {
tryCatch({
//catch区块
it.printStackTrace()
onLoginListener.loginFailed(it.toString())
}) {
//try区块
loginAsync?.cancelByActivite()//存活取消
loginAsync = RetrofitHelper.retrofitService.loginWanAndroid(username, password)
val result = loginAsync?.await()
result ?: let {
onLoginListener.loginFailed(Constant.RESULT_NULL)
return@async
}
result?.let { onLoginListener.loginSuccess(it) }
}
}
}
override fun registerWanAndroid(
onRegisterListener: HomePresenter.OnRegisterListener,
username: String,
password: String,
repassword: String) {
async(UI) {
tryCatch ({
//catch区块
it.printStackTrace()
onRegisterListener.registerFailed(it.toString())
}) {
//try区块
registerAsync?.cancelByActivite()//存活取消
registerAsync = RetrofitHelper.retrofitService.registerWanAndroid(username,password,repassword)
val result = registerAsync?.await()
result ?: let {
onRegisterListener.registerFailed(Constant.RESULT_NULL)
return@async
}
result?.let { onRegisterListener.registerSuccess(it) }
}
}
}
}