是一个Kotlin写的MVP脚手架。 一般的MVP框架都没有协程的支持。KotMVP将协程的特性引入到MVP中。并且抽象了Model层可以自定义自己的Model。内置Retrofit请求接口。 带来的好处:
- 拥有MVP基本的框架
- Coroutine使代码更加偏向逻辑,更少的关注异步回调
- 拥有与Activity或者Fragment绑定的生命周期,无需关注Model层请求的释放
- MVP
- Coroutine
- Retrofit
gradle加入:
implementation 'com.lhxia.kotmvp:kotmvp:0.0.6'
首先声明一个Contract。里面包含了Presenter以及View的子类
interface AContract: Contract {
interface APresenter: Contract.Presenter
interface AView: Contract.View<APresenter>{
fun setInfo(info : String)
fun showError(error: String)
}
}
class APresenterImpl(override val view : AContract.AView, parentCoroutineContext: CoroutineContext = EmptyCoroutineContext)
: BasePresenter(view, parentCoroutineContext), AContract.APresenter {
}
class MainActivity : BaseMPVActivity<AContract.APresenter>(), AContract.AView {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setPresenter(APresenterImpl(this, coroutineContext))
}
override fun setInfo(info : String) {
haha.text = info
}
override fun showError(error: String) {
toast("error : $error")
}
}
首先实现Model接口,并且在自己的Model接口上添加@Repo(implClass = AModel::class)注解设置实现类。
@Repo(implClass = AModel::class)
class AModel: Model {
fun getInfo() : Model.ModelRequest<String>{
val call = api.getBaidu()
return SrtingRetrofitModelRequest(call)
}
}
直接在Presenter里声明即可
private lateinit var aModel : AModel
抽象接口,自己实现。支持取消操作。注意getResp()为suspend方法支持协程
interface ModelRequest<T> {
@Throws(Exception::class)
suspend fun getResp(): T
fun cancel()
}
如果是retrofit可以使用内置的实现RetrofitModelRequest。
abstract class RetrofitModelRequest<T>(private var call: Call<T>)
: Model.ModelRequest<T> {
override fun cancel() {
call.cancel()
}
}
比如返回值为String的接口。其中DefaultResultDecoder实现ResultDecoder接口为服务器返回解析出具体的类型
class SrtingRetrofitModelRequest(private val call: Call<String>) : RetrofitModelRequest<String>(call) {
override suspend fun getResp(): String {
return call.await(DefaultResultDecoder())
}
}
class DefaultResultDecoder : ResultDecoder<String> {
@Throws(Exception::class)
override fun decode(response: Response<String>) : String {
if (response.isSuccessful) {
return response.body()!!
} else {
throw NetworkErrorException()
}
}
}
可以直接在presenter中使用协程
class APresenterImpl(override val view : AContract.AView, parentCoroutineContext: CoroutineContext = EmptyCoroutineContext)
: BasePresenter(view, parentCoroutineContext), AContract.APresenter {
private lateinit var aModel : AModel
override fun onCreate() {
super.onCreate()
launch {
delay(3000)
view.showError("11111")
val a = aModel.getInfo()
try {
view.setInfo(a.getResp())
} catch (e : NetworkErrorException){
view.showError("网络错误")
}
view.showError("网络错误22222")
}
}
}