preface

Recently, I have a new project to do. When I was building the framework, I sorted out the MVP mode, which is hereby recorded. Welcome your correction.

  • Retrofit2+RXjava encapsulation based on MVP Mode
  • Retrofit2+RXjava package file download based on MVP mode
  • Retrofit2+RXjava package file upload based on MVP mode
  • Common Problems with Retrofit2+RXjava encapsulation based on MVP Mode (iv)
  • MVP mode Retrofit2+RXjava encapsulation breakpoint Download (5)
  • Retrofit2+RXjava Encapsulation based on MVP Mode data preprocessing (6)
  • 【Android architecture 】 Retrofit2+RXjava encapsulation based on MVP mode

First, dependence

The compile 'com. Google. Code. Gson: gson: 2.8.0' compile 'com. Squareup. Okhttp3: okhttp: 3.4.1 track' compile 'com. Squareup. Retrofit2: retrofit: 2.3.0' compile 'IO. Reactivex. Rxjava2: rxandroid: 2.0.1' compile 'the IO. Reactivex. Rxjava2: rxjava: 2.1.5' / / compile ConverterFactory String depend on the bag 'com. Squareup. Retrofit2: converter - scalars: 2.3.0' / / ConverterFactory Gson depend on the compile 'com. Squareup. Retrofit2: converter - gson: 2.3.0' / / CallAdapterFactory Rx depend on the compile 'com. Squareup. Retrofit2: adapter - rxjava2:2.3.0'Copy the code

ApiServer defines some interfaces

public interface ApiServer {
    @POST("shopping_login.htm")
    Observable<String> LoginByRx(@Field("username") String username, @Field("password") String password);

}
Copy the code

ApiRetrofit initializes Retrofit and OkHttpClient and adds interceptors

public class ApiRetrofit {

    public final String BASE_SERVER_URL = "https://wawa-api.vchangyi.com/";

    private static ApiRetrofit apiRetrofit;
    private Retrofit retrofit;
    private OkHttpClient client;
    private ApiServer apiServer;

    private String TAG = "ApiRetrofit";

    /** * Request access to quest * response interceptor */
    private Interceptor interceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            long startTime = System.currentTimeMillis();
            Response response = chain.proceed(chain.request());
            long endTime = System.currentTimeMillis();
            long duration = endTime - startTime;
            MediaType mediaType = response.body().contentType();
            String content = response.body().string();
            Log.e(TAG, "----------Request Start----------------");
            Log.e(TAG, "|" + request.toString() + request.headers().toString());
            Log.e(TAG, "| Response:" + content);
            Log.e(TAG, "----------Request End:" + duration + "Ms -- -- -- -- -- -- -- -- -- --");
            returnresponse.newBuilder() .body(ResponseBody.create(mediaType, content)) .build(); }};public ApiRetrofit(a) {
        client = new OkHttpClient.Builder()
                // Add a log interceptor
                .addInterceptor(interceptor)
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .build();

        retrofit = new Retrofit.Builder()
                .baseUrl(BASE_SERVER_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addConverterFactory(ScalarsConverterFactory.create())
                / / support RxJava2
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(client)
                .build();

        apiServer = retrofit.create(ApiServer.class);
    }

    public static ApiRetrofit getInstance(a) {
        if (apiRetrofit == null) {
            synchronized (Object.class) {
                if (apiRetrofit == null) {
                    apiRetrofit = newApiRetrofit(); }}}return apiRetrofit;
    }

    public ApiServer getApiService(a) {
        returnapiServer; }}Copy the code

1.BaseView, which defines common interfaces

public interface BaseView {
    /** * displays dialog */
    void showLoading(a);

    /** ** hide dialog */

    void hideLoading(a);

    /** * Display error message **@param msg
     */
    void showError(String msg);

    /** * error code */
    void onErrorCode(BaseModel model);
}
Copy the code

2.BaseModel

public class BaseModel<T> implements Serializable {
    private int errcode;
    private String errmsg;
    private T result;

    public int getErrcode(a) {
        return errcode;
    }

    public void setErrcode(int errcode) {
        this.errcode = errcode;
    }

    public String getErrmsg(a) {
        return errmsg;
    }

    public void setErrmsg(String errmsg) {
        this.errmsg = errmsg;
    }

    public T getResult(a) {
        return result;
    }

    public void setResult(T result) {
        this.result = result; }}Copy the code

3.BasePresenter

public class BasePresenter<V extends BaseView> {

    private CompositeDisposable compositeDisposable;


    public V baseView;

    protected ApiServer apiServer = ApiRetrofit.getInstance().getApiService();

    public BasePresenter(V baseView) {

        this.baseView = baseView;
    }

    /** * unbind */
    public void detachView(a) {
        baseView = null;
        removeDisposable();
    }

    /** * return view **@return* /
    public V getBaseView(a) {
        return baseView;
    }


    public void addDisposable(Observable
        observable, BaseObserver observer) {
        if (compositeDisposable == null) {
            compositeDisposable = new CompositeDisposable();
        }
        compositeDisposable.add(observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeWith(observer));


    }

    public void removeDisposable(a) {
        if(compositeDisposable ! =null) { compositeDisposable.dispose(); }}}Copy the code

4.BaseObserver mainly deals with common errors

public abstract class BaseObserver<T> extends DisposableObserver<T> {
    protected BaseView view;
    /** * Failed to parse data */
    public static final int PARSE_ERROR = 1001;
    /** * Network problem */
    public static final int BAD_NETWORK = 1002;
    /** * connection error */
    public static final int CONNECT_ERROR = 1003;
    /** * Connection timed out */
    public static final int CONNECT_TIMEOUT = 1004;


    public BaseObserver(BaseView view) {
        this.view = view;
    }

    @Override
    protected void onStart(a) {
        if(view ! =null) { view.showLoading(); }}@Override
    public void onNext(T o) {
        try {
            BaseModel model = (BaseModel) o;
            if (model.getErrcode() == 0) {
                onSuccess(o);
            } else {
                if(view ! =null) { view.onErrorCode(model); }}}catch(Exception e) { e.printStackTrace(); onError(e.toString()); }}@Override
    public void onError(Throwable e) {
        if(view ! =null) {
            view.hideLoading();
        }
        if (e instanceof HttpException) {
            / / HTTP error
            onException(BAD_NETWORK);
        } else if (e instanceof ConnectException
                || e instanceof UnknownHostException) {
            // Connection error
            onException(CONNECT_ERROR);
        } else if (e instanceof InterruptedIOException) {
            // Connection timed out
            onException(CONNECT_TIMEOUT);
        } else if (e instanceof JsonParseException
                || e instanceof JSONException
                || e instanceof ParseException) {
            // Parsing error
            onException(PARSE_ERROR);
        } else {
            if(e ! =null) {
                onError(e.toString());
            } else {
                onError("Unknown error"); }}}private void onException(int unknownError) {
        switch (unknownError) {
            case CONNECT_ERROR:
                onError("Connection error");
                break;

            case CONNECT_TIMEOUT:
                onError("Connection timed out");
                break;

            case BAD_NETWORK:
                onError("Network problems");
                break;

            case PARSE_ERROR:
                onError("Failed to parse data");
                break;

            default:
                break; }}@Override
    public void onComplete(a) {
        if(view ! =null) { view.hideLoading(); }}public abstract void onSuccess(T o);

    public abstract void onError(String msg);
}
Copy the code

5.BaseActivity, implement BaseView, handle the life cycle of Presenter.

public abstract class BaseActivity<P extends BasePresenter> extends AppCompatActivity implements BaseView {
    public Context context;
    private ProgressDialog dialog;
    public Toast toast;
    protected P presenter;

    protected abstract P createPresenter(a);

    protected abstract int getLayoutId(a);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this;
        setContentView(getLayoutId());
        presenter = createPresenter();
        initView();
        initData();
    }

    public void initData(a) {}public void initView(a) {}@Override
    protected void onDestroy(a) {
        super.onDestroy();
        if(presenter ! =null) { presenter.detachView(); }}/ * * *@param s
     */
    public void showtoast(String s) {
        if (toast == null) {
            toast = Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG);
        }
        toast.show();
    }

    private void closeLoadingDialog(a) {
        if(dialog ! =null&& dialog.isShowing()) { dialog.dismiss(); }}private void showLoadingDialog(a) {

        if (dialog == null) {
            dialog = new ProgressDialog(context);
        }
        dialog.setCancelable(false);
        dialog.show();
    }

    @Override
    public void showLoading(a) {
        showLoadingDialog();
    }


    @Override
    public void hideLoading(a) {
        closeLoadingDialog();
    }


    @Override
    public void showError(String msg) {
        showtoast(msg);
    }

    @Override
    public void onErrorCode(BaseModel model) {}@Override
    public void showLoadingFileDialog(a) {
        showFileDialog();
    }

    @Override
    public void hideLoadingFileDialog(a) {
        hideFileDialog();
    }

    @Override
    public void onProgress(long totalSize, long downSize) {
        if(dialog ! =null) {
            dialog.setProgress((int) (downSize * 100/ totalSize)); }}}Copy the code

Now that the framework is in place, let’s see how it works in a real project.

Let’s simulate landing

1. Define LoginView to inherit from BaseView

public interface LoginView extends BaseView {
    void onLoginSucc(a);
}
Copy the code

2. Define LoginPresenter to inherit from BasePresenter

public class LoginPresenter extends BasePresenter<LoginView> {
    public LoginPresenter(LoginView baseView) {
        super(baseView);
    }

    public void login(String name, String pwd) {

        addDisposable(apiServer.LoginByRx(name, pwd), new BaseObserver(baseView) {
            @Override
            public void onSuccess(Object o) {
                baseView.onLoginSucc();

            }

            @Override
            public void onError(String msg) { baseView.showError(msg); }}); }}Copy the code

3. LoginActivity in use

public class LoginActivity extends BaseActivity<LoginPresenter> implements LoginView {

    private AutoCompleteTextView mEmailView;
    private EditText mPasswordView;

    @Override
    protected LoginPresenter createPresenter(a) {
        return new LoginPresenter(this);
    }

    @Override
    protected int getLayoutId(a) {
        return R.layout.activity_login;
    }

    @Override
    public void initView(a) {
        mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
        mPasswordView = (EditText) findViewById(R.id.password);
        Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
        mEmailSignInButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                // Sample code, sample interfacepresenter.login(mEmailView.getText().toString(), mPasswordView.getText().toString()); }}); }@Override
    public void onLoginSucc(a) {
        //Login Succ

        showtoast("Login successful"); }}Copy the code

Project address: GitHub

Conclusion: The above is the realization of MVP, MVP framework many, suitable for their own good.

Your recognition is the motivation for me to keep updating my blog. If it is useful, please give me a thumbs-up. Thank you