前言
我根據(jù)在項目中使用過 mvp馍驯、mvp+databinding、mvp+Rxjava ,通過閱讀google給出的mvp各種示例朵纷,對mvp進(jìn)行總結(jié)實現(xiàn)mvp+databinding+Rxjava的實現(xiàn)方式;
我對于mvp-databinding-Rxjava的理解
我認(rèn)為在android中M 就是Model 是操作數(shù)據(jù)的地方永脓,在M 中可以調(diào)用各種處理數(shù)據(jù)的Manager袍辞,View 是activity,fragment等常摧,在加上databinding可以在綁定數(shù)據(jù)搅吁,p是連接m與v之間的橋梁,以及控制一些需要在主線程實現(xiàn)的數(shù)據(jù)通過RxAndroid 切換到主線程中落午;我認(rèn)為使用databinding的好處可以不用寫findview谎懦,顯示數(shù)據(jù)的時候直接set進(jìn)去就可以了,不需要通過id在settext的方式板甘,還有就是有一些數(shù)據(jù)是可以不需要切換ui線程党瓮,直接set就可以;而使用Rxjava的好處是可以不需要通過handler就可以實現(xiàn)對線程的切換盐类,可以直接顯示數(shù)據(jù)寞奸;
學(xué)習(xí)經(jīng)歷
在項目中使用過的mvp模式,也使用過mvvm模式在跳,但是一直不知道怎么實現(xiàn)是對的枪萄,在使用過程中總是感覺有一些,感覺不舒服的地方猫妙,先說說我是用mvp的經(jīng)歷瓷翻,主要是用過三種方式,最開始是使用zjutkz的一篇博客選擇恐懼癥的福音!教你認(rèn)清MVC,MVP和MVVM,在這篇博客中我學(xué)會了如何使用mvp齐帚,發(fā)現(xiàn)這個模式實在的太美了妒牙,業(yè)務(wù)與頁面完全分離,實現(xiàn)業(yè)務(wù)的時候只需要實現(xiàn)業(yè)務(wù)就可以对妄,實現(xiàn)頁面只需要實現(xiàn)自己的頁面就好了湘今,不需要關(guān)注太多,而且如果哪一天剪菱,經(jīng)理說界面哪里不好看摩瞎,需要改,直接修改頁面就好了孝常,完全不需要關(guān)注業(yè)務(wù)旗们,如果要是說需求有變化,那么直接改變業(yè)務(wù)模塊就可以了构灸,而且各個模塊之間盡量的實現(xiàn)了解耦上渴,方便以后修改,但是在使用過程中感覺有點麻煩喜颁,之后又看了 MvpFrame一個比較簡單的mvp架構(gòu)驰贷,但是我發(fā)現(xiàn)在使用過程中對項目的侵入性很強(qiáng),也有可能是我的強(qiáng)迫癥洛巢,總是感覺沒有真正的了解mvp括袒,于是決定閱讀google給出的mvp示例 google ,通過在項目中的使用,得出自己的mvp實現(xiàn)方式稿茉;
開始放碼
demo地址
BasePresenter 中主要為了與Activity或者fragment中的生命周期統(tǒng)一锹锰,避免內(nèi)存泄漏
public interface BasePresenter {
void onResume(Context context);
void onStop();
void onDestroy();
}
BaseView中只是對P進(jìn)行綁定,如果要是在Activity中使用可以不去管這個方法漓库;
public interface BaseView<T> { void setPresenter(T presenter);}
BaseModel 對基礎(chǔ)數(shù)據(jù)處理的實現(xiàn),對于事件傳遞我使用了rxjava實現(xiàn)的Rxbus恃慧,不了解的可以看一下我之前的一篇rxbus的博客RxJava實現(xiàn)事件總線 Rxbus代替eventbus 減少庫的使用
/**
* @desc:
* @author: Jiangcy
* @datetime: 2016/9/3
*/
public abstract class BaseModel<T> {
private Subscription rxMainBus;
private Subscription rxThreadBus;
protected Context mContext;
//設(shè)置默認(rèn)接受類型為全部接收
private
@EventType.ReceiveType
int recieveType = EventType.REC_ALL;
protected T mPresenter;
public BaseModel(T mPresenter) {
this.mPresenter = mPresenter;
}
/**
* 進(jìn)入
*/
public void onResume(Context mContext) {
this.mContext = mContext;
initRxbus();
}
/**
* 初始化接收類型
*
* @param recieveType
*/
public void initReciever(@EventType.ReceiveType int recieveType) {
this.recieveType = recieveType;
}
;
/**
* 注冊rxbus事件接收
*/
private void initRxbus() {
rxMainBus = RxBus.getDefault().toObserverable(RxEvent.class)
.filter(new Func1<RxEvent, Boolean>() {
@Override
public Boolean call(RxEvent rxEvent) {
//此處可以通過Rxjava的filter過濾函數(shù)對數(shù)據(jù)進(jìn)行過濾,從而得到自己想要的數(shù)據(jù)
if ((rxEvent.reciveType == recieveType ||
rxEvent.reciveType == EventType.REC_ALL) && (rxEvent.threadType ==
EventType.THREAD_ALL || rxEvent.threadType == EventType.THREAD_UI)) {
return true;
}
return false;
}
})
.observeOn(AndroidSchedulers.mainThread())//設(shè)置為主線程接收數(shù)據(jù)
.subscribe(new Action1<RxEvent>() {
@Override
public void call(RxEvent rxEvent) {
onMainEvent(rxEvent.eventAction, rxEvent.event);
}
},
new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
// TODO: 處理異常
}
});
/**
*
*/
rxThreadBus = RxBus.getDefault().toObserverable(RxEvent.class)
.filter(new Func1<RxEvent, Boolean>() {
@Override
public Boolean call(RxEvent rxEvent) {
//此處可以通過Rxjava的filter過濾函數(shù)對數(shù)據(jù)進(jìn)行過濾渺蒿,從而得到自己想要的數(shù)據(jù)
if ((rxEvent.reciveType == recieveType ||
rxEvent.reciveType == EventType.REC_ALL) && (rxEvent.threadType ==
EventType.THREAD_ALL || rxEvent.threadType == EventType.THREAD_CHILD)) {
return true;
}
return false;
}
})
.observeOn(AndroidSchedulers.mainThread())//設(shè)置為子線程接收數(shù)據(jù)
.subscribe(new Action1<RxEvent>() {
@Override
public void call(RxEvent rxEvent) {
onThreadEvent(rxEvent.eventAction, rxEvent.event);
}
},
new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
// TODO: 處理異常
}
});
}
public abstract void onMainEvent(String action, Object event);
public abstract void onThreadEvent(String action, Object event);
/**
* 解除事件的注銷痢士,以保證不出現(xiàn)內(nèi)存泄漏
*/
public void onDestroy() {
if (rxMainBus != null && !rxMainBus.isUnsubscribed()) {
rxMainBus.unsubscribe();
}
if (rxThreadBus != null && !rxThreadBus.isUnsubscribed()) {
rxThreadBus.unsubscribe();
}
mContext = null;
}
}
還有兩個我封裝的基礎(chǔ)類需要了解一下,不想看的這一步可以掠過嘿嘿茂装,這兩個基礎(chǔ)類主要是通過封裝減少代碼怠蹂;這個目前只是簡單的封裝以后還會對這些部分進(jìn)一步的進(jìn)行封裝;
BaseActivity
public abstract class BaseActivity extends AppCompatActivity {
private ViewDataBinding binding;
protected abstract int getLayoutId();
protected abstract void initBinding(ViewDataBinding binding);
protected abstract void initPresenter();
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this,getLayoutId());
initBinding(binding);
}
@CallSuper
@Override
protected void onResume() {
initPresenter();
super.onResume();
}
@CallSuper
@Override
protected void onDestroy() {
super.onDestroy();
}
}
BaseDialog
public abstract class BaseDialog extends Dialog implements Dialog.OnDismissListener{
private Context mContext;
private ViewDataBinding binding;
public BaseDialog(Context context) {
super(context);
mContext = context;
}
public BaseDialog(Context context, int themeResId) {
super(context, themeResId);
mContext = context;
}
protected BaseDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
super(context, cancelable, cancelListener);
mContext = context;
}
protected abstract int getLayoutId();
protected abstract void initBinding(ViewDataBinding binding);
protected abstract void initInfo(Object... objects);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.inflate(LayoutInflater.from(mContext),getLayoutId(),null,false);
setContentView(binding.getRoot());
}
@Override
protected void onStart() {
super.onStart();
setOnDismissListener(this);
}
public void showDialog(){
if(isShowing())return;
show();
}
public void closeDialog(){
if(!isShowing())return;
dismiss();
}
}
為防止代碼量過大少态,我將會把具體實現(xiàn)方式放在下一篇文章里面給出城侧,google 官方mvp實例的實踐之mvp-databinding-Rxjava(二)