美文网首页安卓框架Android完美封装Android开发
Retrofit2-RxJava-Dagger2-MVP完美封装

Retrofit2-RxJava-Dagger2-MVP完美封装

作者: javalong | 来源:发表于2017-01-03 16:34 被阅读910次

    如果对 Retrofit2+RxJava 封装还不是很了解的话
    可以参考下:
    http://www.jianshu.com/p/17e3e3102c1f
    如果对Dagger2 还不是很了解,可以参考下:
    http://www.jianshu.com/p/cd2c1c9f68d4
    如果对mvp还不是很了解,可以自己百度下,很多的,我就不贴出了.
    下面我简单讲述下:
    请先看下目录结构:

    com
    └── javalong
    └── rrdm
    ├── activity
    │   ├── component
    │   │   ├── LoginActivityComponent.java
    │   │   └── MainActivityComponent.java
    │   ├── iview
    │   │   ├── ILoginView.java
    │   │   └── IMainView.java
    │   ├── LoginActivity.java
    │   ├── MainActivity.java
    │   ├── module
    │   │   ├── LoginActivityModule.java
    │   │   └── MainActivityModule.java
    │   └── presenter
    │       ├── LoginPresenter.java
    │       └── MainPresenter.java
    ├── app
    │   ├── annotation
    │   │   └── ActivityScope.java
    │   ├── AppBaseActivity.java
    │   ├── AppBaseApplication.java
    │   ├── component
    │   │   └── AppComponent.java
    │   ├── iview
    │   │   └── MvpView.java
    │   ├── module
    │   │   └── AppModule.java
    │   └── presenter
    │       └── AppPresenter.java
    └── retrofit
    ├── ResponseMessageBean.java
    ├── RetrofitHelper.java
    ├── ServerApi.java
    ├── TWGsonConverterFactory.java
    ├── TWGsonRequestBodyConverter.java
    ├── TWGsonResponseBodyConverter.java
    └── TWJavaCallAdapterFactory.java
    

    这里我就不对mvp,dagger2和Retrofit2+Rxjava过多介绍了.这里就介绍下具体的封装.
    我这里是一个Presenter和一个Activity(View)相互对应,所以我让Presenter直接在基类中注入.对其进行统一管理:
    AppPresenter.Java:

    /** 
     * Created by javalong on 16-12-27. 
     * presenter基类 
     */  
    public abstract class AppPresenter<V extends MvpView>{  
        @Inject  
        protected V mvpView;  
      
        public AppPresenter(V mvpView) {  
            this.mvpView = mvpView;  
        }  
      
        public abstract void attach();  
        public abstract void detach();  
    }  
    

    AppBaseActivity.java--->所有Activity的基类,对presenter进行统一处理.

    /** 
     * Created by javalong on 16-12-27. 
     */  
      
    public abstract class AppBaseActivity<T extends AppPresenter> extends AppCompatActivity {  
        @Inject  
        protected T mPresenter;  
      
        @Override  
        protected void onCreate(@Nullable Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            initInjects();  
            mPresenter.attach();  
        }  
      
        protected abstract void initInjects();  
      
        @Override  
        protected void onDestroy() {  
            super.onDestroy();  
            mPresenter.detach();  
        }  
      
        protected AppComponent getAppComponent(){  
            return AppBaseApplication.getInstance().getAppComponent();  
        }  
    }  
    

    AppBaseActivity中引用了AppComponent.这个需要在AppBaseApplication进行初始化.Component是dagger2依赖注入的基础.

    AppBaseApplication.java

    /** 
     * Created by javalong on 16-12-27. 
     */  
      
    public class AppBaseApplication extends Application {  
      
        private static AppBaseApplication instance;  
      
        public static AppBaseApplication getInstance() {  
            return instance;  
        }  
      
        AppComponent appComponent;  
      
        public AppComponent getAppComponent() {  
            return appComponent;  
        }  
      
        @Override  
        public void onCreate() {  
            super.onCreate();  
            instance = this;  
            if (appComponent == null) {  
                appComponent = DaggerAppComponent.builder().appModule(new AppModule(this)).build();  
            }  
        }  
    }  
    

    如果不熟悉Dagger2的童鞋,可能会发现没有DaggerAppComponent这个类,不要慌,请'Make Project'编译下项目.DaggerAppComponent会自动生成.DaggerAppComponent其实是根据我们写的AppComponent接口生成的一个类,下面我们先看下AppComponent.

    @Singleton  
    @Component(modules = AppModule.class)  
    public interface AppComponent {  
        Context getContext();  
        ServerApi getServerApi();  
    }  
    

    AppComponent这个接口其实很简单.这里记得要加上@Scope注解(@Singleton是@Scope的一种)使Component和Module中provide出来的对象联系起来.
    关于@Scope注解的含义我这里就不过多介绍了,大家可以参考我上面推荐的文章.写的很不错.
    接下来看下AppModule中提供了哪些依赖

    @Module  
    public class AppModule {  
      
        private Context mContext;  
      
        public AppModule(Context context) {  
            this.mContext = context;  
        }  
      
        @Provides @Singleton  
        Context provideContext(){  
            return mContext;  
        }  
      
        @Provides @Singleton  
        ServerApi provideServerApi(Context context){  
            RetrofitHelper.init(context);  
            return RetrofitHelper.getApi();  
        }  
      
    }  
    

    这里的@Singleton 和前面AppComponent的@Singleton 相互连接,让我们造成了单例的假象.其实@Singleton并没有单例的作用,是因为
    和AppComponent一起使用,AppComponent只创建了一次,所以产生'单例'这个现象.(我这里又重复得说了一边,汗~~)
    AppComponent和AppModule请根据自己项目的详细情况来进行封装,由于我这个demo比较简单,所以只@Provides 了2个对象出来.

    下面我来详细介绍下Activity和Presenter之间的封装.
    首先我这里先说明下,我这里的一个Activity,对应着1个view,1个presenter,1个component,1个module.
    可能封装的不是很好,没有领悟到mvp的精髓,但是对我来说更加清晰.
    MainActivity.java

    public class MainActivity extends AppBaseActivity<MainPresenter> implements IMainView{  
      
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.activity_main);  
            mPresenter.test();  
        }  
      
        @Override  
        protected void initInjects() {  
            DaggerMainActivityComponent.builder()  
                    .appComponent(getAppComponent())  
                    .mainActivityModule(new MainActivityModule(this))  
                    .build()  
                    .inject(this);  
        }  
      
      
        @Override  
        public void showMainMessage() {  
            ((TextView)findViewById(R.id.tv_test))  
                    .setText("你好 dagger");  
            findViewById(R.id.bt_login)  
            .setOnClickListener(new View.OnClickListener() {  
                @Override  
                public void onClick(View v) {  
                    LoginActivity.start(MainActivity.this);  
                    MainActivity.this.finish();  
                }  
            });  
        }  
    }  
    

    MainActivity必须继承AppBaseActivity,然后传入泛型,即对应的Presenter的类型.在initInjects中必须完成Dagger2的注入操作,因为在AppBaseActivity中的Presenter需要
    注入,如果不注入,在基类中调用mPresenter.attach会出错.
    当你使用Dagger2的时候,其实很明显会暴露他的一个缺点,必须要编译后,才能产生对应的Dagger**Component.当然相对于他的好处来讲,这点还是可以忍受的.
    前面提到了必须要对基类中的Presenter进行注入,那么到底注入的是什么呢?这里我以MainPresenter为例.

    public class MainPresenter extends AppPresenter<IMainView>{  
      
        @Inject  
        public MainPresenter(IMainView mvpView) {  
            super(mvpView);  
        }  
      
        @Override  
        public void attach() {  
      
        }  
      
        @Override  
        public void detach() {  
      
        }  
      
        public void test() {  
            mvpView.showMainMessage();  
        }  
    }  
    

    MainActivityModule.java

    @Module  
    public class MainActivityModule  {  
      
        private IMainView mainView;  
      
        public MainActivityModule(IMainView mainView) {  
            this.mainView = mainView;  
        }  
      
        @Provides @ActivityScope IMainView provideIMainView(){  
            return mainView;  
        }  
      
        /** 
         * 这种方式,和直接在MainPresenter构造方法上添加@Inject是一样的 
         * 二选一即可. 
         */  
    //    @Provides @ActivityScope MainPresenter provideMainPresenter(IMainView mainView){  
    //        return new MainPresenter(mainView);  
    //    }  
    }  
    

    看注释,这里有2种方式可以完成MainPresenter的注入,一种是直接在MainPreenter的构造方法上加上@Inject,一种是在对应的Module中使用
    @Provides 把MainPresenter提供出来. 至于@ActivityScope其实是和前面@Scope一样的,我这里就不过多介绍了.
    最关键的一步:
    MainActivityComponent.java

    @ActivityScope  
    @Component(dependencies = AppComponent.class,modules = MainActivityModule.class)  
    public interface MainActivityComponent{  
        /** 
         * @param mainView 
         * 这里必须使用MainActivity,不能使用IMain接口 
         * 否则会造成@Inject注入失败 
         */  
        void inject(MainActivity mainView);  
    } 
    

    必须在对应的Component提供注入方法(名字不一定叫inject).
    MainActivity.java 部分代码

    @Override  
       protected void initInjects() {  
           DaggerMainActivityComponent.builder()  
                   .appComponent(getAppComponent())  
                   .mainActivityModule(new MainActivityModule(this))  
                   .build()  
                   .inject(this);  
       }  
    

    这样才完成了注入.
    DaggerMainActivityComponent中会先对AppBaseActivity进行注入,然后再对MainActivity进行注入.
    这里我简单的讲述了封装,如果还有什么不懂的地方可以再交流~~~github: https://github.com/javalong/Retrofit2-RxJava-Dagger2-MVP

    相关文章

      网友评论

        本文标题:Retrofit2-RxJava-Dagger2-MVP完美封装

        本文链接:https://www.haomeiwen.com/subject/exrnvttx.html