• How to design a good network framework, I have no answer in mind, I have seen a lot of other people’s wheels, some are too simple, limited too complex, some to meet the request of the network, praise or criticism
  • The network framework of this article is based on the upgraded version of my network framework three years ago, please see MVP Network framework (Retorfit+Rxjava+Rxandroid) here.

Join the rely on

    api "Com. Squareup. Retrofit2: retrofit: 2.5.0"
    api "Com. Squareup. Retrofit2: converter - gson: 2.5.0"
    api "Com. Squareup. Retrofit2: adapter - rxjava2:2.5.0"
    api 'the IO. Reactivex. Rxjava2: rxandroid: 2.1.0'
    api 'the IO. Reactivex. Rxjava2: rxjava: 2.2.2'
    api "Com. Squareup. Okhttp3: logging - interceptor: 3.12.0"
Copy the code
  • rxjava: is the reaction expansionJava VMImplementation: a library for composing asynchronous and event-based programs using observable sequences.
  • rxandroid: This module addressesRxJavaAdd the minimum number of classes so that theAndroidWriting reactive components in your application is easy and hassle-free. More specifically, it is provided in the main thread or in anyLooperThe upper scheduler.
  • converter-gsonThrough:GsonConverterFactoryforRetrofitaddGsonsupport
  • logging-interceptor: You can intuitively observe the diary of network requests
  • adapter-rxjava2: One for adaptationRXJava 2Type of adapter.

Build a Network Framework

  • IMvpView
* @param errorCode * @param errorMsg */ void getDataFail(String errorCode, String errorMsg); @param e */ void onError(Throwable e); }Copy the code
  • IPresenter processing and View lifecycle
Public interface IPresenter<V extends IMvpView> {@param mvpView */ void attachView(V mvpView); /* detachView(); /* detachView(); }Copy the code
  • BasePresenterallPresenterBase class, and bind allActivityLife cycle of
public class BasePresenter<V extends IMvpView> implements IPresenter<V> {


    private V mMvpView;

    @Override
    public void attachView(V mvpView) {
        mMvpView = mvpView;
    }

    @Override
    public void detachView() { mMvpView = null; } /** * determine whether the * @ is still connectedreturn
     */
    public boolean isViewAttached() {
        returnmMvpView ! = null; } public VgetMvpView() {
        returnmMvpView; } /** * Check if the View is attached */ public voidcheckViewAttached() {
        if(! isViewAttached()) throw new MvpViewNotAttachedException(); } public static class MvpViewNotAttachedException extends RuntimeException { publicMvpViewNotAttachedException() {
            super("Make sure you bind views before you bind data."); }} /** * This is the onServer in the Observer, when we call this method, * @disposable */ public void dispose(disposable disposable) {if (disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
    }
}
Copy the code
  • General structure drawing

The network framework DataManager

  • According to the design ideas of the previous articleHement MVP Architecture Design (1)
  • You can knowDataManagerNot only do you need to handle network requests, but you also need to handle local storageSharedPreferencesandSQLite
  • So instead, the DataManager provides data objects to the outside world. The processing of the data is already done for you. When you use the data, you just need to get the object instance you want
@Singleton
public class DataManager {


    private final IRemoteServer mIRemoteServer;
    private final PreferencesHelper mPreferencesHelper;
    private final DatabaseHelper mDatabaseHelper;

    @Inject
    public DataManager(IRemoteServer server, PreferencesHelper preferencesHelper, DatabaseHelper databaseHelper) {
        mIRemoteServer = server;
        mPreferencesHelper = preferencesHelper;
        mDatabaseHelper = databaseHelper;
    }

    public void loadData(String key, String day, BaseObserver observer) {
        Observable<SMResponse<ArrayList<TodayBean>>> today = mIRemoteServer.getToday(key, day);
        today.observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(observer);
    }

    public PreferencesHelper getPreferencesHelper() {
        returnmPreferencesHelper; } /** * fetch data from the network, cache it to the database, and fetch data from the database * @return
     */
    public Observable<TodayBean> syncDBBean() {
        return mIRemoteServer.getToday("b15674dbd34ec00ded57b369dfdabd90"."1/1").concatMap(new Function<SMResponse<ArrayList<TodayBean>>, ObservableSource<? extends TodayBean>>() {
            @Override
            public ObservableSource<? extends TodayBean> apply(@NonNull SMResponse<ArrayList<TodayBean>> response)
                    throws Exception {
                returnmDatabaseHelper.setDBData(response.result); }}); } /** * fetch data from the database * @return
     */
    public Observable<List<TodayBean>> getDBBean() {
        returnmDatabaseHelper.getDBData().distinct(); }}Copy the code

How is the network framework used

  • Here is the use of aggregated data interface, here thanks to the selfless contribution, three years of this interface can still be used, very grateful
http://v.juhe.cn/todayOnhistory/queryEvent.php?key=b15674dbd34ec00ded57b369dfdabd90&date=1/1
Copy the code
  • 1, Define the remote Server:IRemoteServerI’m going to take the previous one and generate it separatelyRetrofittheServerDrawn to theIRemoteServerBecause the project usesDagger2, introduced later
public interface IRemoteServer { /** * The key * http://v.juhe.cn/todayOnhistory/queryEvent.php?key=b15674dbd34ec00ded57b369dfdabd90&date=1/1 * @ param key application @param date Date * @returnReturn to today in history */ @get ("queryEvent.php")
    Observable<SMResponse<ArrayList<TodayBean>>> getToday(@Query("key") String key, @Query("date") String date);

    class Creator {
        public static IRemoteServer newHementService() {
          returnSMRetrofit.getService(HementApplication.getContext(), IRemoteServer.class); }}}Copy the code
  • 2,DataManagerThe result is called back toAndroidSchedulers.mainThread()Threads, that’s androidUIThreads.
   private final IRemoteServer mIRemoteServer;
    private final PreferencesHelper mPreferencesHelper;
    private final DatabaseHelper mDatabaseHelper;

    @Inject
    public DataManager(IRemoteServer server, PreferencesHelper preferencesHelper, DatabaseHelper databaseHelper) {
        mIRemoteServer = server;
        mPreferencesHelper = preferencesHelper;
        mDatabaseHelper = databaseHelper;
    }

    public void loadData(String key, String day, BaseObserver observer) {
        Observable<SMResponse<ArrayList<TodayBean>>> today = mIRemoteServer.getToday(key, day);
        today.observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(observer);
    }
Copy the code
  • 3,NetWorkPresenterdefine
@ConfigPersistent
public class NetWorkPresenter  extends BasePresenter<NetWorkView> {

    private final DataManager mDataManager;

    private Disposable mDisposable;

    @Inject
    public NetWorkPresenter(DataManager dataManager) {
        mDataManager = dataManager;
    }

    @Override
    public void attachView(NetWorkView mvpView) {
        super.attachView(mvpView);
    }

    @Override
    public void detachView() {
        super.detachView();
        if(mDisposable ! = null) mDisposable.dispose(); } public void loadData(String key,String day){// Check whether the View is attached to it. Dispose (mDisposable) dispose(mDisposable) mDataManager.loadData(key,day,new BaseObserver<SMResponse<ArrayList<TodayBean>>>(new SubscriberListener<SMResponse<ArrayList<TodayBean>>>() { @Override public void onSubscribe(Disposable disposable) { super.onSubscribe(disposable); mDisposable = disposable; } @Override public void onSuccess(SMResponse<ArrayList<TodayBean>> response) { getMvpView().getDataSuccess(response.result); } @Override public void onFail(String errorCode, String errorMsg) { getMvpView().getDataFail(errorCode,errorMsg); } @Override public void onError(Throwable e) { getMvpView().onError(e); }})); }}Copy the code
  • 4, inActivityThrough Dagger2 dependency injectionNetWorkPresenterAnd at the same timeonDestroy()The destruction ofRxJava2If the Activity is shut down, the network request may be in progress, so it needs to be destroyed.
public class NetWorkActivity extends BaseActivity implements NetWorkView, View.OnClickListener {

    String key="b15674dbd34ec00ded57b369dfdabd90";
    @Inject
    NetWorkPresenter mMainPresenter;

    private Button mBtn;
    private EditText mDay;
    private EditText mMonth;
    private RecyclerView mRecyclerView;
    private SMAdapter mSmAdapter;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        activityComponent().inject(this);
        setContentView(R.layout.activity_net_work);
        Timber.tag(getClassName()).i("mMainPresenter =%s",mMainPresenter);
        mMainPresenter.attachView(this);
        initView();
        initListener();
    }
    private void initView() {
        mBtn = (Button) findViewById(R.id.btn);
        mMonth = (EditText) findViewById(R.id.et_month);
        mDay = (EditText) findViewById(R.id.et_day);
        mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
    }
    private void initListener() {
        mBtn.setOnClickListener(this);
        mSmAdapter = new SMAdapter(this, null);
        mRecyclerView.setAdapter(mSmAdapter);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    }

    @Override
    public void getDataFail(String errorCode, String errorMsg) {
        Toast.makeText(this,errorMsg+errorCode,Toast.LENGTH_LONG).show();
    }

    @Override
    public void onError(Throwable e) {
        Toast.makeText(this,e.toString(),Toast.LENGTH_LONG).show();
    }

    @Override
    public void getDataSuccess(ArrayList<TodayBean> result) {
        String s = new Gson().toJson(result);
        Timber.tag(getClassName()).i(s);
        Thread thread = Thread.currentThread();
        Timber.tag(getClassName()).i(thread.toString());
        mSmAdapter.addData(result);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMainPresenter.detachView();
    }

    @Override
    public void onClick(View v) {
        if (TextUtils.isEmpty(mMonth.getText())||TextUtils.isEmpty(mDay.getText())){
            Toast.makeText(NetWorkActivity.this,"Can't be empty.",Toast.LENGTH_SHORT).show();
        }else {
            mMainPresenter.loadData(key,mMonth.getText()+"/"+mDay.getText()); }}}Copy the code
  • To be continued to the next article

  • GitHub address: Hement: Updates continuously