Retrofit2-RxJava-Dagger2-MVP完美封装 [复制链接]

2017-9-8 10:36
James1991 阅读:2527 评论:0 赞:1
Tag:  

如果对 Retrofit2+RxJava 封装还不是很了解的话

可以参考下:


如果对Dagger2 还不是很了解,可以参考下:


如果对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

分享到:
我来说两句
facelist
您需要登录后才可以评论 登录 | 立即注册
所有评论(0)

领先的中文移动开发者社区
18620764416
7*24全天服务
意见反馈:1294855032@qq.com

扫一扫关注我们

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 粤ICP备15117877号 )