深入浅出 php mvp,Hement:MVP架构中的网络框架

GitHub地址:Hement:持续更新中

由于使用Dagger2的未知性,所以创建一个分支没有使用Dagger2  Hement如何设计好网络框架,我心中也没答案,看过很多别人的轮子,有些太简单,有限过于复杂,有些为了满足去请求网络,褒贬不一

加入依赖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:可以很直观的观察到网络请求的日记

AAffA0nNPuCLAAAAAElFTkSuQmCC

image.png

AAffA0nNPuCLAAAAAElFTkSuQmCC

image.png

adapter-rxjava2:一个用于适应RXJava 2类型的适配器。

搭建网络框架IMvpViewpublic interface IMvpView {  /**

* 数据失败的同一处理

* @param errorCode

* @param errorMsg

*/

void getDataFail(String errorCode, String errorMsg);  /**

* 发成异常的同一处理

* @param e

*/

void onError(Throwable e);

}IPresenter  处理和View的生命周期public interface IPresenter {    /**

* 和view结合

* @param mvpView

*/

void attachView(V mvpView);    /**

* 和view 断开

*/

void detachView();

}BasePresenter 所有Presenter的基类,同时绑定所有Activity的生命周期public class BasePresenter implements IPresenter {    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();

}

}

}总体结构图

AAffA0nNPuCLAAAAAElFTkSuQmCC

总体结构图

网络框架DataManagerAAffA0nNPuCLAAAAAElFTkSuQmCC

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>> today = mIRemoteServer.getToday(key, day);

today.observeOn(AndroidSchedulers.mainThread())

.subscribeOn(Schedulers.io())

.subscribe(observer);

}    public PreferencesHelper getPreferencesHelper() {        return mPreferencesHelper;

}    /**

* 从网络获取数据,缓存到数据库,然后从数据库中取数据

* @return

*/

public Observable syncDBBean() {        return mIRemoteServer.getToday("b15674dbd34ec00ded57b369dfdabd90", "1/1").concatMap(new Function>, ObservableSource extends TodayBean>>() {            @Override

public ObservableSource extends TodayBean> apply(@NonNull SMResponse> response)                    throws Exception {                return mDatabaseHelper.setDBData(response.result);

}

});

}    /**

* 从数据库中取数据

* @return

*/

public Observable> getDBBean() {        return mDatabaseHelper.getDBData().distinct();

}

}

网络框架如何使用这里使用的是聚合数据的接口 ,在这里感谢无私的贡献,三年了这个接口还能用,万分感谢http://v.juhe.cn/todayOnhistory/queryEvent.php?key=b15674dbd34ec00ded57b369dfdabd90&date=1/11、定义远程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>> 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>> today = mIRemoteServer.getToday(key, day);

today.observeOn(AndroidSchedulers.mainThread())

.subscribeOn(Schedulers.io())

.subscribe(observer);

}3、NetWorkPresenter定义@ConfigPersistentpublic class NetWorkPresenter  extends BasePresenter {    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>>(new SubscriberListener>>() {            @Override

public void onSubscribe(Disposable disposable) {                super.onSubscribe(disposable);

mDisposable = disposable;

}            @Override

public void onSuccess(SMResponse> 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 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());

}

}

}

作者:豌豆射手_BiuBiu

链接:https://www.jianshu.com/p/e46cace343a4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值