Hement:MVP架构中的网络框架(RxJava2+Retrofit2+RxAndroid)(二)
- GitHub地址:Hement:持续升级中
- 因为使用Dagger2的未知性,所以创立一个分支没有使用Dagger2 Hement
- 如何设计好网络框架,我心中也没答案,看过很多别人的轮子,有些太简单,有限过于复杂,有些为了满足去请求网络,褒贬不一
- 本文的网络框架基于我三年前的网络框架的更新版,具体请看这里 MVP网络框架(Retorfit+Rxjava+Rxandroid)
加入依赖
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 'io.reactivex.rxjava2:rxandroid:2.1.0' api 'io.reactivex.rxjava2:rxjava:2.2.2' api "com.squareup.okhttp3:logging-interceptor:3.12.0"rxjava:是反应式扩展的Java VM实现:一个用于使用可观察序列组成异步和基于事件的程序的库。rxandroid:这个板块向RxJava增加了最少的类,使得在Android应用程序中编写反应性组件变得简单且无麻烦。更具体地说,它提供了在主线程或者在任何Looper上调度的调度器。converter-gson:通过GsonConverterFactory为Retrofit增加Gson支持logging-interceptor:可以很直观的观察到网络请求的日记
image.png
image.pngadapter-rxjava2:一个用于适应RXJava 2类型的适配器。
搭建网络框架
- IMvpView
public interface IMvpView { /** * 数据失败的同一解决 * @param errorCode * @param errorMsg */ void getDataFail(String errorCode, String errorMsg); /** * 发成异常的同一解决 * @param e */ void onError(Throwable e);}- IPresenter 解决和View的生命周期
public interface IPresenter<V extends IMvpView> { /** * 和view结合 * @param mvpView */ void attachView(V mvpView); /** * 和view 断开 */ void detachView();}BasePresenter所有Presenter的基类,同时绑定所有Activity的生命周期
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; } /** * 判断能否还在连接在一起的 * @return */ public boolean isViewAttached() { return mMvpView != null; } public V getMvpView() { return mMvpView; } /** * 检查View能否附着 */ public void checkViewAttached() { if (!isViewAttached()) throw new MvpViewNotAttachedException(); } public static class MvpViewNotAttachedException extends RuntimeException { public MvpViewNotAttachedException() { super("在绑定数据之前肯定要绑定视图"); } } /** * 这是Observer 中的 onServer ,当我们调用这个方法,直接就不会走到 onNext中去 * @param disposable */ public void dispose(Disposable disposable) { if (disposable != null && !disposable.isDisposed()) { disposable.dispose(); } }}总体结构图
总体结构图
网络框架DataManager
- 根据上篇文章的设计思路 Hement:MVP架构设计(一)
Android中的MVP模式.jpg - 可以知道
DataManager不仅仅是解决网络请求那么简单,同时还需要解决本地存储SharedPreferences和SQLite - 所以就转变成了,DataManager向外界提供数据对象,数据的解决已经帮您解决好了,使用的时候只要要获取你想要的对象实例,即可以了,具体封装如下
@Singletonpublic 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() { return mPreferencesHelper; } /** * 从网络获取数据,缓存到数据库,而后从数据库中取数据 * @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 { return mDatabaseHelper.setDBData(response.result); } }); } /** * 从数据库中取数据 * @return */ public Observable<List<TodayBean>> getDBBean() { return mDatabaseHelper.getDBData().distinct(); }}网络框架如何使用
- 这里使用的是聚合数据的接口 ,在这里感谢无私的贡献,三年了这个接口还能用,万分感谢
http://v.juhe.cn/todayOnhistory/queryEvent.php?key=b15674dbd34ec00ded57b369dfdabd90&date=1/1- 1、定义远程Server:
IRemoteServer,在这里我把以前的单独生成的Retrofit的Server抽取到IRemoteServer,由于项目使用了Dagger2,后面详情
public interface IRemoteServer { /** * http://v.juhe.cn/todayOnhistory/queryEvent.php?key=b15674dbd34ec00ded57b369dfdabd90&date=1/1 * @param key 申请的key * @param date 日期 * @return 返回历史上的今天 */ @GET("queryEvent.php") Observable<SMResponse<ArrayList<TodayBean>>> getToday(@Query("key") String key, @Query("date") String date); class Creator { public static IRemoteServer newHementService() { return SMRetrofit.getService(HementApplication.getContext(), IRemoteServer.class); } }}- 2、
DataManager中的线程调度,结果回调到AndroidSchedulers.mainThread()线程,就是安卓的UI线程。
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); }- 3、
NetWorkPresenter定义
@ConfigPersistentpublic 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){ //检查View能否附着在上面,不在直接抛出异常 checkViewAttached(); //检查能否往下运行 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); } })); }}- 4、在
Activity中的使用,通过Dagger2依赖注入NetWorkPresenter,同时在onDestroy()中,销毁RxJava2正在调度的任务,个人了解的就是,关闭Activity,网络请求也有可能是在执行中,所以需要销毁。
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,"不能为空",Toast.LENGTH_SHORT).show(); }else { mMainPresenter.loadData(key,mMonth.getText()+"/"+mDay.getText()); } }}未完待续 Hement:关于项目中的Dagger2的使用(三)
GitHub地址:Hement:持续升级中
说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Hement:MVP架构中的网络框架(RxJava2+Retrofit2+RxAndroid)(二)
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Hement:MVP架构中的网络框架(RxJava2+Retrofit2+RxAndroid)(二)