Android builds a useful MVP framework (Retrofit+Rxjava2+ButterKnife)

Keywords: Retrofit ButterKnife REST

Preface

Recently, I have seen a lot of MVP frameworks in the new project, and then I built the MVP framework myself. So I summarize them here and hope you can learn from each other.

I. Basic Architecture

The structure of MVP is briefly introduced, full name: Model-View-Presenter; it is evolved from the classical model MVC, their basic ideas have something in common:
Controller/Presenter is responsible for processing logic
Model provides data
View is responsible for display

First, let's have a look at the catalogue. Have a basic understanding.

1. Base Series

The base series is designed to make it easy to write public code.
BasePresenter

public interface BasePresenter {
    void subscribe();

    void unSubscribe();
}

These two methods are defined to control the life cycle of objects in Presenter. This is also an optimization of the MVP framework.

BaseView

public interface BaseView<T> {

}

The other two are not shown. They are almost the same.

II. Construction of MainActivity

1,MainContart

interface MainContract {
    interface View extends BaseView<Presenter> {
        void onError(String s);

        void onSuccess(BookBean bookBean);
    }

    interface Presenter extends BasePresenter {
        void getData(String search);
    }
}

This class exists in order to unify the methods of managing View and Presenter. The new method should be written directly here and then go to the corresponding page alt+Enter.
Here the generic T of View is set to the Presenter interface below.

II. MainPresenter

And then get this Presenter

class MainPresenter implements MainContract.Presenter {
    private MainContract.View view;

    MainPresenter(MainContract.View view) {
        this.view = view;
    }

    @Override
    public void subscribe() {
    }

    @Override
    public void unSubscribe() {
    }

    @Override
    public void getData(String search) {
    }
}

This is where the View layer is bound in the constructor.

Then post a Presenter class with the content already written.

class MainPresenter implements MainContract.Presenter {
    private MainContract.View view;
    private CompositeDisposable compositeDisposable;

    MainPresenter(MainContract.View view) {
        this.view = view;
        compositeDisposable = new CompositeDisposable();
    }

    @Override
    public void subscribe() {
    }

    @Override
    public void unSubscribe() {
        compositeDisposable.clear();
    }

    @Override
    public void getData(String search) {
        RetrofitManager.getInstance().getServer().searchBook("Princeling")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<BookBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        compositeDisposable.add(d);
                    }

                    @Override
                    public void onNext(BookBean value) {
                        view.onSuccess(value);
                    }

                    @Override
                    public void onError(Throwable e) {
                        view.onError(e.toString());
                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }
}

III. MainActivity

Finally, inherit the View interface in the activity interface

public class MainActivity extends AppCompatActivity implements MainContract.View {
    @BindView(R.id.activity_text)
    TextView textView;

    private MainContract.Presenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        presenter = new MainPresenter(this);
        presenter.getData("data");
    }

    @Override
    protected void onResume() {
        super.onResume();
        presenter.subscribe();
    }

    @Override
    protected void onPause() {
        super.onPause();
        presenter.unSubscribe();
    }

    @Override
    public void onError(String s) {
        Log.e("error", s);
    }

    @Override
    public void onSuccess(BookBean bookBean) {
        textView.setText(bookBean.toString());
    }
}

Initialize the MainPresenter class in onCreate.

Retrofit+Rxjava2

RetrofitManager Management Tool Class:

public class RetrofitManager {
    private Retrofit retrofit;

    private RetrofitManager() {
        init();
    }

    private void init() {
        OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
                Request original = chain.request();
                Request.Builder requestBuilder = original.newBuilder();
                //Request Body Customization: Unified Addition of token Parameters
                if (original.body() instanceof FormBody) {
                    FormBody.Builder newFormBody = new FormBody.Builder();
                    requestBuilder.method(original.method(), newFormBody.build());
                }
                Request request = requestBuilder.build();
                return chain.proceed(request);
            }
        }).build();

        retrofit = new Retrofit.Builder()
                .baseUrl(SERVER_HOST)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .callFactory(client)
                .build();

    }

    public ApiService getServer() {
        return retrofit.create(ApiService.class);
    }

    public static RetrofitManager getInstance() {
        return RetrofitManagerHolder.INSTANCE;
    }

    private static class RetrofitManagerHolder {
        private static final RetrofitManager INSTANCE = new RetrofitManager();
    }

}

ApiService interface class:

public interface ApiService {
    @GET("v2/book/search")
    Observable<BookBean> searchBook(@Query("tag") String tag);
}

The study of these two methods of use is to search for learning materials separately, which is still very rich.

summary

Here is the basic MVP framework I used in my project. It feels OK in practice. I haven't touched MVP with MVC before, but it's not difficult to really use MVP. As long as I take the first step, the rest are OK.
If you have any comments on my framework, you are welcome to point out in your comments. Thank you very much.

Posted by kaedus on Mon, 31 Dec 2018 10:36:08 -0800