前言:虽然现在已经mvvm了,但是mvp对于新鸟来说,还是一个不错的入门级开发框架,这里就造一个lifecycle的mvp。
起初:mvp的轮子有很多了。大多数情况下是在activity/fragment的生命周期绑定presenter,然后在生命周期内初始化,或者释放,我这个轮子也没有什么特别的地方,也是遵循这一套,最近在看了MvpArm的源码设计后,由于本人太菜,不太会dagger2,又很欣赏arm中以lifecycle绑定presenter的做法,所以将dagger2抽离,造了个简易的lifecycle绑定presenter的轮子
这是MVPArms,个人觉得这确实是个不错的快速开发框架,里面集成了基本全部的开发所需,而且作者还提供了插件,掌握的话,可以节约很多开发时间和改bug时间来干自己想干的事
找工作.jpgBaseActivity/BaseFragment
直接上代码
/**
* baseActivity基类
* 视图层,可自行拓展沉浸式等
* 如果定义增多,建议新增IActivity接口以做规范
*/
abstract class BaseActivity : RxAppCompatActivity(), LifecycleObserver {
private var mUnbinder: Unbinder? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(getLayout())
mUnbinder = ButterKnife.bind(this)
if (useEventBus()) {
//register event
}
initView()
}
/**
* 布局的layout
*/
abstract fun getLayout(): Int
/**
* 是否使用eventBus
*/
abstract fun useEventBus(): Boolean
/**
* 视图回调,这里是子类的开始
*/
abstract fun initView()
override fun onDestroy() {
super.onDestroy()
if (mUnbinder != null && mUnbinder !== Unbinder.EMPTY) {
mUnbinder!!.unbind()
}
mUnbinder = null
if (useEventBus()) {
// unRegister event
}
}
}
BaseFragment同理,这两个基类是基础继承,在不使用mvp的时候,直接继承即可,base的作用不必多说,里面可以封装自己项目的逻辑
然后是
BaseMvpActivity(BaseMvpFragment)
/**
* mvp
*/
abstract class BaseMvpActivity<P : IPresenter> : BaseActivity(), IView {
private var mPresenter: P? = null
/**
* onCreate中创建presenter
*/
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mPresenter = setUpPresenter()
}
/**
* 默认不使用eventBus
*/
override fun useEventBus(): Boolean {
return false
}
abstract fun setUpPresenter(): P?
override fun onDestroy() {
super.onDestroy()
mPresenter?.onDestroy()
mPresenter = null
}
var mStatusView: MultipleStatusView? = null
override fun showLoading() {
if (mStatusView == null) {
val mViewRoot = window.decorView.findViewById<ViewGroup>(android.R.id.content).getChildAt(0) as ViewGroup
if (mViewRoot.childCount != 0) {
for (i in 0 until mViewRoot.childCount) {
if (mViewRoot.getChildAt(i) is MultipleStatusView) {
mStatusView = mViewRoot.getChildAt(i) as MultipleStatusView
mStatusView?.setOnRetryClickListener {
onReLoad()
}
break
}
}
}
}
mStatusView?.showLoading()
}
override fun showEmpty() {
mStatusView?.showEmpty()
}
override fun showError() {
mStatusView?.showEmpty()
}
override fun hideLoading() {
mStatusView?.showContent()
}
var mAlertDialog: AlertDialog? = null
override fun showDialogLoading() {
mAlertDialog = AlertDialog.Builder(this, R.style.Theme_AppCompat_Dialog)
.setView(R.layout.load_dialog_layout)
.setCancelable(true).show()
}
override fun hideDialogLoading() {
mAlertDialog?.dismiss()
}
override fun onReLoad() {
}
override fun showMessage(tipMessage: String?) {
//Toast this
Toast.makeText(this, tipMessage, Toast.LENGTH_SHORT).show()
}
override fun findActivity(): RxAppCompatActivity {
return this
}
override fun findFragment(): RxFragment? {
return null
}
}
BaseMvpActivity/BaseMvpFragment处理presenter的创建,和资源的释放销毁
BasePresenter
/**
* @author chenke
* @create 2020/6/30
* @Describe
*/
public class BasePresenter<M extends IModel, V extends IView> implements IPresenter, LifecycleObserver {
protected CompositeDisposable mCompositeDisposable;
protected M mModel;
protected V mRootView;
/**
* 如果当前页面同时需要 Model 层和 View 层,则使用此构造函数(默认)
*
* @param model
* @param rootView
*/
public BasePresenter(M model, V rootView) {
this.mModel = model;
this.mRootView = rootView;
onStart();
}
/**
* 如果当前页面不需要操作数据,只需要 View 层,则使用此构造函数
*
* @param rootView
*/
public BasePresenter(V rootView) {
this.mRootView = rootView;
onStart();
}
public BasePresenter() {
}
@Override
public void onStart() {
//将 LifecycleObserver 注册给 LifecycleOwner 后 @OnLifecycleEvent 才可以正常使用
if (mRootView != null && mRootView instanceof LifecycleObserver) {
//activity ,fragment绑定自身生命周期
((LifecycleOwner) mRootView).getLifecycle().addObserver(this);
if (mModel != null && mModel instanceof LifecycleObserver) {
//activity ,fragment绑定model数据层的生命周期,当Activity销毁时,数据层感知其生命周期
((LifecycleOwner) mRootView).getLifecycle().addObserver((LifecycleObserver) mModel);
}
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
void onDestroy(LifecycleOwner owner) {
/**
* 注意, 如果在这里调用了 {@link #onDestroy()} 方法, 会出现某些地方引用 {@code mModel} 或 {@code mRootView} 为 null 的情况
* 比如在 {@link RxLifecycle} 终止 {@link Observable} 时, 在 {@link io.reactivex.Observable#doFinally(Action)} 中却引用了 {@code mRootView} 做一些释放资源的操作, 此时会空指针
* 或者如果你声明了多个 @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) 时在其他 @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
* 中引用了 {@code mModel} 或 {@code mRootView} 也可能会出现此情况
*/
owner.getLifecycle().removeObserver(this);
}
public void addDispose(Disposable disposable) {
if (mCompositeDisposable == null) {
mCompositeDisposable = new CompositeDisposable();
}
mCompositeDisposable.add(disposable);//将所有 Disposable 放入容器集中处理
}
/**
* 停止集合中正在执行的 RxJava 任务
*/
public void unDispose() {
if (mCompositeDisposable != null) {
mCompositeDisposable.clear();//保证 Activity 结束时取消所有正在执行的订阅
}
}
@Override
public void onDestroy() {
unDispose();
if (mModel != null) {
mModel.onDestroy();
}
this.mModel = null;
this.mRootView = null;
}
}
activity/fragment 绑定了将生命周期和BasePresenter/Model,绑定,这样当activity/fragment生命周期法伤变化是,,base和model作为观察者
可以,观察到生命周期的变化
核心代码
@Override
public void onStart() {
//将 LifecycleObserver 注册给 LifecycleOwner 后 @OnLifecycleEvent 才可以正常使用
if (mRootView != null && mRootView instanceof LifecycleObserver) {
//activity ,fragment绑定自身生命周期
((LifecycleOwner) mRootView).getLifecycle().addObserver(this);
if (mModel != null && mModel instanceof LifecycleObserver) {
//activity ,fragment绑定model数据层的生命周期,当Activity销毁时,数据层感知其生命周期
((LifecycleOwner) mRootView).getLifecycle().addObserver((LifecycleObserver) mModel);
}
}
}
所以BasePresenter和model都要实现lifecycle的观察者接口
public class BasePresenterimplements IPresenter, LifecycleObserver
open class BaseModel : IModel, LifecycleObserver
因为model为数据交互层,所以需要retrofit的实例
BaseModel
/**
* @author chenke
* @create 2020/6/30
* @Describe
*/
open class BaseModel : IModel, LifecycleObserver {
protected var mRepositoryManager: IRepositoryManager? = null
/**
* model层为数据层,所以需要retrofit实例来请求网络
*/
constructor(repositoryManager: IRepositoryManager) {
this.mRepositoryManager = repositoryManager
}
/**
* presenter在onDestroy时调用
* 释放资源
*/
override fun onDestroy() {
mRepositoryManager = null
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy(owner: LifecycleOwner) {
owner.lifecycle.removeObserver(this)
}
}
现在,我们就用这个简易的生命周期感知mvp来写一个demo吧
界面如下
界面.jpg
xml就忽略了
WeatherActivity mvp的网络请求界面
class WeatherActivity : BaseMvpActivity<TestPresenter>(), TestContact.TestView {
override fun setUpPresenter(): TestPresenter? {
return TestPresenter(TestModel(RepositoryManager()), this)
}
override fun initView() {
}
override fun getLayout(): Int {
return R.layout.activity_weather_activty
}
override fun bindTest(): TextView {
return tv_content
}
}
题外话:因为presenter在setContentView初始化,所以在presenter调用时TextView已经完成了初始化
presenter
presenter的创建
override fun setUpPresenter(): TestPresenter? {
return TestPresenter(TestModel(RepositoryManager()), this)
}
这里RepositoryManager是retrofit的实例创建类
RepositoryManager
/**
* @author chenke
* @create 2020/6/30
* @Describe retrofit网络创建层
*/
public class RepositoryManager : IRepositoryManager {
private val URL_1 = "http://wthrcdn.etouch.cn/"
var retrofit1 = Retrofit.Builder()
.baseUrl(URL_1)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build()
fun <T> create(serviceClass: Class<T>): T = retrofit1.create(serviceClass)
private var apiHost1: ApiHost1? = null
override fun getApiHost1(): ApiHost1 {
if (apiHost1 == null) {
apiHost1 = create(ApiHost1::class.java)
}
return apiHost1 as ApiHost1
}
override fun getApiHost2() {
}
override fun getApiHost3() {
}
}
IRepositoryManager是管理retrofit url接口文件,可以将不同模块的url做拆分,也可以建立不同的baseurl(不同baseurl的retrofit客户端,或者针对每个url接口文件的baseurl通过常量来管理请求)
/**
* @author chenke
* @create 2020/6/30
* @Describe
*/
interface IRepositoryManager {
/**
* 对应不同的baseUrl
*/
fun getApiHost1(): ApiHost1
fun getApiHost2()
fun getApiHost3()
}
TestPresente
constructor(model: TestContact.TestModel, rootView: TestContact.TestView) :super(model, rootView)
我们再回过头来看super(model,rootView)
/**
* 如果当前页面同时需要 Model 层和 View 层,则使用此构造函数(默认)
*
* @param model
* @param rootView
*/
public BasePresenter(M model, V rootView) {
this.mModel = model;
this.mRootView = rootView;
onStart();
}
@Override
public void onStart() {
//将 LifecycleObserver 注册给 LifecycleOwner 后 @OnLifecycleEvent 才可以正常使用
if (mRootView != null && mRootView instanceof LifecycleObserver) {
//activity ,fragment绑定自身生命周期
((LifecycleOwner) mRootView).getLifecycle().addObserver(this);
if (mModel != null && mModel instanceof LifecycleObserver) {
//activity ,fragment绑定model数据层的生命周期,当Activity销毁时,数据层感知其生命周期
((LifecycleOwner) mRootView).getLifecycle().addObserver((LifecycleObserver) mModel);
}
}
}
这里onStart()将presenter和model作为activity/fragment的生命周期观察者,一切的根源
现在presenter就可以感知activity的生命周期变化了
TestPresenter.onCreate
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreate() {
Log.i("gw", "activity onCreate")
mRootView.showDialogLoading()
mModel.getWeather2("成都")
.delay(2000, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(mRootView.findActivity().bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(object : Observer<ResponseBean<WeatherBean>> {
override fun onComplete() {
mRootView.hideDialogLoading()
}
override fun onSubscribe(d: Disposable) {
addDispose(d)
}
override fun onError(e: Throwable) {
e.printStackTrace()
mRootView.bindTest().text = "${e.message}"
}
override fun onNext(t: ResponseBean<WeatherBean>) {
Log.i("gw", "请求成功")
mRootView.showMessage("请求成功")
mRootView.bindTest().text = "${t.data.city}"
}
})
}
这里在activityonCreate的时候直接请求了接口数据
然后mRootView(WeatherActivity)来刷新UI展示
效果如下
效果.gif完整的TestPresenter
TestPresenter
/**
* @author chenke
* @create 2020/7/7
* @Describe
*/
class TestPresenter : BasePresenter<TestContact.TestModel, TestContact.TestView> {
constructor(model: TestContact.TestModel, rootView: TestContact.TestView) : super(model, rootView)
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreate() {
Log.i("gw", "activity onCreate")
mRootView.showDialogLoading()
mModel.getWeather2("成都")
.delay(2000, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.compose(mRootView.findActivity().bindUntilEvent(ActivityEvent.DESTROY))
.subscribe(object : Observer<ResponseBean<WeatherBean>> {
override fun onComplete() {
mRootView.hideDialogLoading()
}
override fun onSubscribe(d: Disposable) {
addDispose(d)
}
override fun onError(e: Throwable) {
e.printStackTrace()
mRootView.bindTest().text = "${e.message}"
}
override fun onNext(t: ResponseBean<WeatherBean>) {
Log.i("gw", "请求成功")
mRootView.showMessage("请求成功")
mRootView.bindTest().text = "${t.data.city}"
}
})
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onActivityDestroy() {
Log.i("gw", "activity finish")
Log.i("gw", "mRootView:$mRootView")
}
override fun onDestroy() {
super.onDestroy()
Log.i("gw", "presenter销毁了")
Log.i("gw", "mRootView:$mRootView")
}
}
接下来,我们观察下log各个生命周期日志
onCreate的时候
onCreate.jpgWeatherActivity点击回退finish的时候
完整生命周期.jpg
model中感知activity/fragment的生命周期
#TestModel
/**
* @author chenke
* @create 2020/7/7
* @Describe
*/
class TestModel : BaseModel, TestContact.TestModel {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onActivityDestroy() {
Log.i("gw", "model感知activity生命周期---finish")
}
constructor(repositoryManager: IRepositoryManager) : super(repositoryManager)
override fun getWeather(): Observable<ResponseBean<WeatherBean>> {
return mRepositoryManager?.getApiHost1()?.weather()!!
}
override fun getWeather2(city: String): Observable<ResponseBean<WeatherBean>> {
return mRepositoryManager?.getApiHost1()?.weather2(city)!!
}
}
至此,简易的生命周期感知的mvp就完成了,附上demo,你可以down下来做你想要的修改
生命周期感知MVPDemo
网友评论