实战mvp+rxjava+retrofit+dagger框架经验之谈

原创 2018年04月16日 20:24:23

前言

2016年的尾声mvp+rxjava+retrofit这套框架。可以说是风靡,但是当时的我只是在其他大神的博客中看看,没有深入了解,原因也是当时项目着急,没有精力去学习,2017年初,公司运营不善,换了新工作,0到1的项目,也使我有了实战这套风靡的框架。。。

我先说我搭建封装的结构后面有解析

关键类贴出:

public abstract class BasePresenterImpl<T extends BaseContract.BaseView> implements BaseContract.BasePresenter<T> {

    protected T mView;
    protected CompositeSubscription mCompositeDisposable;
    protected CompositeSubscription RxBusSubscriptions;

    protected ApiStores apiStores;

    @Override
    public void attachView(T view) {
        mView = view;
        apiStores = AppClient.retrofit().create(ApiStores.class);       //retrofit初始化
        mCompositeDisposable = new CompositeSubscription();
        RxBusSubscriptions = new CompositeSubscription();
        attachView();
    }

    @Override
    public void detachView() {
        mCompositeDisposable.unsubscribe();
        RxBusSubscriptions.clear();
        RxBusSubscriptions.unsubscribe();
    }

    protected abstract void attachView();


    protected T getView() {
        return mView;
    }

    protected CompositeSubscription getSubscription() {
        return mCompositeDisposable;
    }

    @Override
    public void subscribe() {
    }

    @Override
    public void unsubscribe() {
        mCompositeDisposable.clear();
    }

    public void addSubscription(Observable observable, Subscriber subscriber) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeSubscription();
        }
        mCompositeDisposable.add(observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber));
    }

}

Presenter控制逻辑,也就是控制网络操作,绑定数据,一系列逻辑都在这.

那么,当activity关闭以后,Presenter怎么处理网络请求,异步操作呢?

比如上面的loadData(),如果acitivity已经关闭了,而网络操作又没走完.

就会内存泄漏.会不会空指针不好说.

view虽然持有p,但是也不能在Activity的onDestroy里面直接的将p=null吧

对象=null也只是断开引用而已,还并不是真的释放.

这样没用的,而且p还持有view呢,异步也不会因此结束,

所以得有个接口告诉p,我要挂了,你也自杀吧.

所以:

interface BasePresenter {

  void onStart();

   void onDestroy();

}

让所有的Presenter都继承BasePresenter,然后在activity中相应的生命周期里面调用

在相应的方法里面,初始化,结束异步操作,释放资源,将view=null;

而在activity里面,由于Presenter并没有view的引用了,

所以p随着activity的销毁也就跟着销毁了.不会造成上下文的泄漏等.

正确代码:

public interface BasePresenter<T extends BaseView> {

    void attachView(T view);

    void detachView();

    void subscribe();

    void unsubscribe();
}

在BaseActiuvity生命周期

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

@Override
protected void onStop() {
    super.onStop();
    mPresenter.unsubscribe();
}
@Override
protected void onDestroy() {
    super.onDestroy();
    mPresenter.detachView();
   
}

MVP设计模式

不算是个新鲜的东西了,大概解读下:

M层 : model 模型.

也可以理解成bean对象,我觉得不全是, 用获取数据比较贴切.

在以前写mvc的时候,我习惯抽成initData()来表示modle.

public interface Model {

  Bean load(String url,params)

}

modle,我推荐用retrofit2+rxjava来写,完全适用啊,对比一看,是不是感觉几乎没区别?

V层:view视图

在mvp中,有人把activity/fragment理解成presenter,

我觉得还是理解成v好一点,

比较纠结是,activity有生命周期,怎么就是单纯的v呢.

但如果理解成presenter的话,那么和mvc区别就不大了吧.

具体使用: 
1.写一个view接口

public interface View {

 //抽取相对的activity里面的各种行为

//如:

 void show();

 void bindData(Bean b);

}

2,activity实现这个设计好的view接口

public class MainActivity extends Activity implements View{

Presenter presenter;

@Override

 protected voidonCreate(Bundle savedInstanceState) {

           super.onCreate(savedInstanceState); 

           setContentView(R.layout.activity_main);

          presenter = new Presenter(this);

}

 public void show(){

 }

 public void bindData(Bean b){

      ........

     //等待数据,设置view.

 }

}

3,实现每个行为的逻辑:对某个控件做什么事.

public void show(){

//具体操作.比如弹个toast啥的,设置某个控件啥的

}

4.持有presenter

这里有点难理解,持有presenter是什么意思?

我们不管做什么操作,都是一次事件

而这个事件由谁接收,当然是activity接收了.

如果activity不持有presenter,怎么告诉presenter,我需要获得数据.

p:控制 presenter

一般写法:

public interface Presenter {

   void loadData();

}

public interface PresenterImpl implements Presenter {

 View v;

 public PresenterImpl(View v){

      this.v = v;

}

publc void loadData(){    

     Modler  modle   =    new  Modle();//创建modle

     Bean  bean =  modle.load("url",params);//获得数据 

     v.bindData(bean);//数据绑定view

}

}

总结:

presenter和view相互持有调用,presenter可以同时操作Modle和View,但是Modle和View之间不能调用.

Retrifit

它的作用介绍我就不多废话。

重点

public class AppClient {

    private static final String TAG = "AppClient";

    public static Retrofit mRetrofit;

    public static Retrofit retrofit() {
        if (mRetrofit == null) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder();

            if (BuildConfig.DEBUG) {
                // Log信息拦截器
                HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
                    @Override
                    public void log(String message) {
                        Logger.t(TAG).i(message);
                    }
                });

                logging.setLevel(HttpLoggingInterceptor.Level.BODY);
                builder.addInterceptor(logging);
            }

            OkHttpClient okHttpClient = builder.build();
            okHttpClient.networkInterceptors();
            okHttpClient.connectTimeoutMillis();
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(AppNetConfig.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .client(okHttpClient)
                    .build();
        }
        return mRetrofit;
    }

}

在baseactivty中初始化Presenter,接下来就是在basePresenter中初始化Retrofit了

源代码如下:别忘记在结束时取消订阅

public abstract class BasePresenterImpl<T extends BaseContract.BaseView> implements BaseContract.BasePresenter<T> {

    protected T mView;
    protected CompositeSubscription mCompositeDisposable;
    protected CompositeSubscription RxBusSubscriptions;

    protected ApiStores apiStores;

    @Override
    public void attachView(T view) {
        mView = view;
        apiStores = AppClient.retrofit().create(ApiStores.class);       //retrofit初始化
        mCompositeDisposable = new CompositeSubscription();
        RxBusSubscriptions = new CompositeSubscription();
        attachView();
    }

    @Override
    public void detachView() {
        mCompositeDisposable.unsubscribe();
        RxBusSubscriptions.clear();
        RxBusSubscriptions.unsubscribe();
    }

    protected abstract void attachView();


    protected T getView() {
        return mView;
    }

    protected CompositeSubscription getSubscription() {
        return mCompositeDisposable;
    }

    @Override
    public void subscribe() {
    }

    @Override
    public void unsubscribe() {
        mCompositeDisposable.clear();
    }

    public void addSubscription(Observable observable, Subscriber subscriber) {
        if (mCompositeDisposable == null) {
            mCompositeDisposable = new CompositeSubscription();
        }
        mCompositeDisposable.add(observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber));
    }

}
总结:实战中可以先简单的搭建,一点一滴的完善你的框架希望对你有所帮组。大神轻喷(一个顺手的框架史书很重要哦)有不懂的同学可以加我qq咨询425043853,答案随便写。
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/whj0207/article/details/79965530

用Java通过DIIOP远程操作Domino服务器

最近在玩domino,积累点经验大家分享一下: 开发notes本来就是摸着石头过河,随时会碰到怪问题,结合上java更辛苦:( 但是notes有一些优点,比如全文检索,安全性,开发时效...所以至今仍...
  • steeven
  • steeven
  • 2001-11-22 23:02:00
  • 3641

程序员经验之谈

在看hadoop配置的时候,无意间看到了这本书,感觉挺好的,转载一下供大家学习一下,希望能帮到你,也非常感谢原文的作者。。。。。。 原文链接:http://www.cnblogs.com/xia52...
  • lpf1990823
  • lpf1990823
  • 2013-12-13 14:05:01
  • 405

一位IT牛人的十年经验之谈

1、分享第一条经验:“学历代表过去、能力代表现在、学习力代表未来。”   其实这是一个来自国外教育领域的一个研究结果。相信工作过几年、十几年的朋友对这个道理有些体会吧。但我相信这一点也很重要:“...
  • u014234850
  • u014234850
  • 2015-01-23 23:10:14
  • 669

Tensorflow实战Google深度学习框架-学习笔记

tensor:张量,是tensorflow的数据模型。在tensorflow中可以简单理解为多位数组,表示计算节点,是tensorflow管理数据的形式。但是在tensorflow中,张量的实现并不是...
  • u013163281
  • u013163281
  • 2017-07-19 17:04:23
  • 1549

TensorFlow实战Google深度学习框架(一)

第一章  深度学习简介 1.    人工有时候无法很好的抽取实体中的特征,那么是否有自动的方式?是的,深度学习解决的核心问题之一就是自动的将简单的特征合成更加复杂的特征,使用这些组合特征解决问题。 2...
  • zhujianing1993
  • zhujianing1993
  • 2017-04-03 02:45:38
  • 3421

linux经验之谈

1.Linux和Unix的区别     首先,linux的核心是免费的和公开的,开发是处于一个完全开放的环境之中,所以用户对其有很高的自主权。但是unix的核 心源并不公开,它侧重于对源代...
  • felixldf
  • felixldf
  • 2017-03-05 16:30:50
  • 100

《Tensorflow:实战Google深度学习框架》 PDF版

  • 2017年11月01日 14:06
  • 96.65MB
  • 下载

《TensorFlow:实战google深度学习框架》代码错误_第五章MNIST

交叉熵函数参数改变,所以需要改一下, 改正cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits=y,labels...
  • liukcqu
  • liukcqu
  • 2017-10-31 21:55:41
  • 701

《Tensorflow:实战Google深度学习框架》高清完整PDF版

  • 2017年06月16日 20:43
  • 96.7MB
  • 下载

TensorFlow实战Google深度学习框架第三章总结

该文主要是总结了Tensorflow实战Google深度学习框架的第三章,修正了代码中一些不存在函数的修改。...
  • wyl1813240346
  • wyl1813240346
  • 2017-10-25 20:45:47
  • 575
收藏助手
不良信息举报
您举报文章:实战mvp+rxjava+retrofit+dagger框架经验之谈
举报原因:
原因补充:

(最多只允许输入30个字)