After finishing the first version of the last project, only by summarizing and analyzing the architecture of the last project can we find the shortcomings of the structure and build the most perfect architecture of our own.


1. The subcontract

—— My subcontracting is as follows:

API: Put some classes related to network requests, such as configuring Retrofit

Base: A base class for activities, fragments, and Presenter

Common: Put some common classes that are used globally, such as Application

The model: My model layer only contains bean classes, which are divided into Request and Response. Different from the traditional MVP model, the model layer of the traditional MVP requests network data, and then the P layer gets the references of m layer and V layer, so that m layer and V layer interact, but that is too much code. Each request creates a Model class, and for an introduction, I put the request network data directly into the P layer, as you’ll see later in the code.

Presenter: Puts the Presenter class

Utils: Put in some utility classes

Viewinterface: Puts the View interface class

Viewimpl: Puts the View implementation class

Widget: Displays custom views

—— Because the project is not big and has few interfaces, I adopt this kind of subcontracting. If the project has many functional modules, it is better to subcontract by functional modules, with a clear structure. The following figure is a project with many functional modules that I have done before:


2. The MVP

The MVP framework has been on the rise since 2016, and more and more Android developers are using it to develop their apps. MVP combined with RxJava and Retrofit is pretty cool. Since using MVP combined with RxJava and Retrofi, the code is clean, the logic is clear, the call is elegant, and the maintenance cost is low. For this company project I used MVP + RxJAVA2 + RetroFIT2 + Butterknife.

The MVP framework uses annotations, factory mode, and proxy mode to solve code redundancy, memory leaks, presenter lifecycle, and data storage problems. By using generics to bind a view to a presenter, you can call getPresenter() directly from the view to request network data, and call getView() directly from the View to get the View to update the interface. The request network is packaged with RXJava + RetroFIT, adding network request and response interceptors. The network request and response JSON is directly visible in Logcat in Android Studio.


3. use

Your API

Public interface WApi {// Get the list of movies @post ("/PageSubArea/TrailerList.api")
    Flowable<MoiveListResponse> getMoiveList();

}
Copy the code

First, define a view interface IMoiveListView

/**
 * Created by JokerWan on 2017/12/11.
 * WeChat: wjc398556712
 * Function:
 */
public interface IMoiveListView extends IWanBaseView{

    void onLoading();

    void onLoadSucess(MoiveListResponse moiveListResponse);

    void onLoadFail(String msg);
}
Copy the code

The use of an Activity (similar to Fragment use) creates a Presenter using the @createPresenter annotation

/**
 * Created by JokerWan on 2017/12/11.
 * WeChat: wjc398556712
 * Function:
 */
@CreatePresenter(MoiveListPresenter.class)
public class MainActivity extends AWanBaseActivity<IMoiveListView,MoiveListPresenter>
        implements IMoiveListView {

    @BindView(R.id.tv_moive_name)
    TextView tvMoiveName;
    @BindView(R.id.img_moive)
    ImageView imgMoive;

    @Override
    public int getViewLayoutId() {
        return R.layout.activity_main;
    }

    @Override
    public void initData(Bundle savedInstanceState) {
        if(null ! = savedInstanceState) {// TODO: 2017/12/11 data recovery} getPresenter().getMoivelist (); } @Override public voidonLoading() {
        tvMoiveName.setText("Data loading, please wait..."); } @Override public void onLoadSucess(MoiveListResponse moiveListResponse) { MoiveListResponse.TrailersBean trailersBean = moiveListResponse.getTrailers().get(1); tvMoiveName.setText(trailersBean.getMovieName()); Glide .with(this) .load(trailersBean.getCoverImg()) .into(imgMoive); } @Override public void onLoadFail(String msg) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); }}Copy the code

The use of the presenter

/**
 * Created by JokerWan on 2017/12/11.
 * WeChat: wjc398556712
 * Function:
 */

public class MoiveListPresenter extends AWanBasePresenter<IMoiveListView> {

    public void getMoiveList(){

        getView().onLoading();

        wApi.getMoiveList()
                .compose(ApiUtils.getScheduler())
                .subscribe(new ApiSubscriber<MoiveListResponse>() {
                    @Override
                    public void onNext(MoiveListResponse moiveListResponse) {
                        if(moiveListResponse ! = null) { getView().onLoadSucess(moiveListResponse); } } @Override public void onError(Throwable t) { getView().onLoadFail(t.getMessage()); }}); }}Copy the code

4. Demo effect after running