關於MVP、Retrofit、RxJava,之前已經分別做了分享,如果您還沒有閱讀過,可以猛戳:
3、RxJava
4、RxBus
假設,您對MVP、Retrofit、RxJava已經有了一點了解,那么我們開始本文:
Android MVP優化
1、MVP綁定Activity(Fragment)生命周期
按照之前的文章,每個Presenter都得初始化和銷毀,我新加MvpActivity(MvpFragment),加了抽象方法protected abstract P createPresenter();
這樣做的目的在需要使用MVP的地方,可以繼承MvpActivity(MvpFragment),然后初始化和銷毀就不用手動一個個去加了。
2、接口請求等還是放到MVP的P中
這個圖片,在當時寫MVP文章時給出的,實際開發中,我發現每個都這樣寫,實在是增加了不少代碼,然接口請求放到P中,還有個好處,就是MVP綁定Activity(Fragment)生命周期,當onDestroy時取消RXJava注冊,以避免內存泄露。
代碼
目錄結構
如圖,有個大致了解:
mvp:所有的mvp都放在這個包下
retrofit:Retrofit接口和配置文件
rxjava:RxJava一些回調設置
ui:Activity或fragment,建議按功能再細分包
核心代碼
還是就貼出核心代碼吧,源碼在我的github上(https://github.com/WuXiaolong/AndroidMVPSample)。
MainActivity入口,還是演示的之前的MVP的天氣的接口,接口請求方法放在Presenter。
MvpActivity
Presenter綁定Activity(Fragment)生命周期
public abstract class MvpActivity<P extends BasePresenter> extends BaseActivity {
protected P mvpPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
mvpPresenter = createPresenter();
super.onCreate(savedInstanceState);
}
protected abstract P createPresenter();
@Override
protected void onDestroy() {
super.onDestroy();
if (mvpPresenter != null) {
mvpPresenter.detachView();
}
}
}
MainPresenter
apiStores.loadData方法是Retrofit做的網絡請求,回調是RxJava完成的。
public class MainPresenter extends BasePresenter<MainView> {
public MainPresenter(MainView view) {
attachView(view);
}
public void loadData(String cityId) {
mvpView.showLoading();
addSubscription(apiStores.loadData(cityId),
new SubscriberCallBack<>(new ApiCallback<MainModel>() {
@Override
public void onSuccess(MainModel model) {
mvpView.getDataSuccess(model);
}
@Override
public void onFailure(int code, String msg) {
mvpView.getDataFail(msg);
}
@Override
public void onCompleted() {
mvpView.hideLoading();
}
}));
}
}
apiStores.loadData
是不是很簡單,關於Retrofit配置,詳見源碼AppClient。
public interface ApiStores {
//baseUrl
String API_SERVER_URL = "http://www.weather.com.cn/";
//加載天氣
@GET("adat/sk/{cityId}.html")
Observable<MainModel> loadData(@Path("cityId") String cityId);
}
RxJava回調方法
這里onError,寫了如果網絡請求用httpcode來判斷。當然可以不要。
public class SubscriberCallBack<T> extends Subscriber<T> {
private ApiCallback<T> apiCallback;
public SubscriberCallBack(ApiCallback<T> apiCallback) {
this.apiCallback = apiCallback;
}
@Override
public void onCompleted() {
apiCallback.onCompleted();
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
if (e instanceof HttpException) {
HttpException httpException = (HttpException) e;
//httpException.response().errorBody().string()
int code = httpException.code();
String msg = httpException.getMessage();
if (code == 504) {
msg = "網絡不給力";
}
apiCallback.onFailure(code, msg);
} else {
apiCallback.onFailure(0, e.getMessage());
}
apiCallback.onCompleted();
}
@Override
public void onNext(T t) {
apiCallback.onSuccess(t);
}
}
BasePresenter
再來看看BasePresenter,這里做了Presenter初始化和銷毀(包括RXjava取消注冊),調用在MvpActivity。
public class BasePresenter<V> implements Presenter<V> {
public V mvpView;
public ApiStores apiStores = AppClient.retrofit().create(ApiStores.class);
private CompositeSubscription mCompositeSubscription;
@Override
public void attachView(V mvpView) {
this.mvpView = mvpView;
}
@Override
public void detachView() {
this.mvpView = null;
onUnsubscribe();
}
//RXjava取消注冊,以避免內存泄露
public void onUnsubscribe() {
if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) {
mCompositeSubscription.unsubscribe();
}
}
public void addSubscription(Observable observable, Subscriber subscriber) {
if (mCompositeSubscription == null) {
mCompositeSubscription = new CompositeSubscription();
}
mCompositeSubscription.add(observable
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber));
}
}
源碼地址
https://github.com/WuXiaolong/AndroidMVPSample
總結
三者結合使用,重點還是對MVP的優化,Retrofit只貼出最簡單的(后續會寫Retrofit詳情使用),Rxjava可能我是對它認識尚淺,實際運用最多還是RxBus。
微信公眾號
歡迎微信掃一掃關注:不止於技術分享,每天進步一點點。