About MVP, Retrofit, and RxJava, I have shared them before. If you haven't read them, you can poke them:
3 、RxJava
4、RxBus
Assuming that you already have a little understanding of MVP, Retrofit, RxJava, let's start this article:
Android MVP optimization
1. MVP binding Activity (Fragment) life cycle According to the previous article, each Presenter has to be initialized and destroyed. I added MvpActivity (MvpFragment), and added an abstract method protected abstract P createPresenter();
. The purpose of this is that where MVP needs to be used, it can be inherited MvpActivity(MvpFragment), and then initialization and destruction do not need to be added manually one by one.
2. The interface request, etc. are still placed in the P of the MVP. This picture was given when the MVP article was written at that time. In actual development, I found that each of them was written in this way, which really added a lot of code, but the interface request was placed in the In P, another advantage is that MVP binds the Activity (Fragment) life cycle and cancels the RXJava registration when onDestroy to avoid memory leaks.
code
Directory Structure
As shown in the figure, there is a general understanding: mvp: All mvp are placed under this package retrofit: Retrofit interface and configuration file rxjava: RxJava some callback settings ui: Activity or fragment, it is recommended to subdivide the package by function
core code
Let's just post the core code, the source code is on my github ( https://github.com/WuXiaolong/AndroidMVPSample ).
The MainActivity entry is also the interface of the previous MVP weather demonstrated, and the interface request method is placed in the Presenter.
MvpActivity
Presenter binds Activity (Fragment) life cycle
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
The apiStores.loadData method is a network request made by Retrofit, and the callback is done by 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
Is it very simple? For the Retrofit configuration, see the source code 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 callback method
Here onError, it is written that if the network request is judged by httpcode. Of course not.
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
Let's take a look at BasePresenter, where Presenter initialization and destruction (including RXjava deregistration) are done, and the call is made in 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));
}
}
Source address
https://github.com/WuXiaolong/AndroidMVPSample
Summarize
When the three are used together, the focus is still on the optimization of MVP. Retrofit only posts the simplest one (the details of Retrofit will be written later), Rxjava may be my knowledge of it, and the most practical application is RxBus.
WeChat public account
Welcome to WeChat scan and pay attention: more than technology sharing, make a little progress every day.