组件化架构Dagger2无缝连接开发

96
cuieney
0.5 2017.11.08 13:44* 字数 1523

前言

可以说已经一个多月没有更新了,mdzz这个月一直在赶项目节奏,可算是度过了这个阶段。也不能说这个月没有收获,新项目中又总结了不少经验,这次就来分享一下所感所得吧,记得之前写过一篇文章说的是组件化开发详解这篇文章可能与他息息相关。只不过是把Dagger引入了组件化开发项目中,之前那篇文章的重点是如何搭建一个组件化架构,方便团队开发配合。这篇文章的重点是把dagger引入组件化开发架构中,之前搭建组件化开发也没想到用Dagger引入项目,因为坑不是一般的多,各种错误,各种bug,让你头疼。这篇文章会把这些问题一一阐述,达到无缝连接

坑列表

大部分都是放置位置的问题。这样会让你减少很多module里面的代码

  1. 组件化架构Dagger如何配置
  2. Module放置位置
  3. XXXComponent位置如何放置,不会出现找不到Module
  4. Base App/Activity/Fragment 如何封装

各个Module的Gradle Dagger配置

先把简单的架构图放上面 方便下面一一叙述


从上图可以看出每个module都会依赖于最下层的Library

1.那么我们先说在Library的gradle中如何配置吧

dependencies {
  compile 'com.google.dagger:dagger:2.x'
  annotationProcessor 'com.google.dagger:dagger-compiler:2.x'
}

2.那么接下来我们来看看Module中如何配置Gradle文件呢!

dependencies {
  annotationProcessor 'com.google.dagger:dagger-compiler:2.x'
}

看到上面代码是不是很惊讶,为什么在上层module中为什么还要重复依赖呢,出现了同样的配置。

 annotationProcessor 'com.google.dagger:dagger-compiler:2.x'

大家应该都明白这行代码的主要功能是用于生成代码的。底层library里面不是已经有了吗?为什么在上层module中还出现呢?这是一个坑。下面我会一一解释

Dagger Module放置位置

其实dagger 中的Module的放置位置很重要,因为module 是用于component注入到各个Activity里面的,之前的mv*这些架构Di这些东西都是放在Application module里面的,但是我们既然是组件化开发,肯定要知道我们的初衷,我们的BaseLibrary到底是干嘛的。给上层module提供各种工具各种方便,让各个module开发互相不干扰。

那么当然是把各种module放在最底层的library中的了如ActivityModule, FragmentModule,AppModule 这些我只是简单的举例,可能还有很多Module,其实这里说到module 可能也会明白上面的为什么在最底层library中也添加代码生成

 annotationProcessor 'com.google.dagger:dagger-compiler:2.x'

为了生成相应的module代码。提供上面component使用。

XXXComponent位置如何放置,不会出现找不到Module

这个问题也是我在开发中出现的,由于之前只是在mv*架构中使用Dagger 在组件化架构中开发知道坑多,没用Dagger,那么我们来看看如何放置我们的Activity/Fragment/App Component等等这些位置。这里我只举例而我们的ActivityComponent和AppComponent的放置位置。

1.AppComponent如何放置,当然是放在我们的BaseLibrary中了,因为是App全局都需要用的,所以我们这个可以写在我们最底层的Library中,然后上层module都可以用到。其实之前我是每个Module都放的,发现这样写真是很多冗余的代码,没有脱离mvp那
个结构 导致的。

2.ActivityComponent如何放置呢?可能会比较麻烦因为每个上层Module用到的都要放置一个对应的ActivityComponent

@PerActivity
@Component(dependencies = BaseAppComponent.class, modules = ActivityModule.class)
public interface ActivityComponent {
    Activity getActivity();
    void inject(VoiceActivity mainActivity);
ity);
}

从上面代码也可以看出 我们为什么每个组件Module为什么都放置一个ActivityComponent,因为如果你放置在底层Library中,你根本不知道你的哪个activity要用到,而且library也是拿不到上层Module里面的任何东西 底层library只是一个供给者 而非索取者。

但是我们的AppComponent不需要知道我们需要哪些东西,我们只是负责提供东西。

Base App/Activity/Fragment 如何封装

如果你的项目按照上面的配置,这时你已经绕过了很多坑的地方

说道封装Base 这时候需要提到一个问题就是之前那一篇文章说道了一个问题 module与Application之间调用的问题 我也提供了解决方案,就是在底层Library中写个BaseApplication来供上层调用。

那么我们回归正题,这里只说App 和 Activity的Base封装

  1. 底层Library中的BaseApp如何封装呢?看代码
public abstract class BaseApp extends Application {
    protected static BaseApp app;
    public static BaseApp getInstance() {
        return app;
    }
    
    protected abstract void initSDK();

    public BaseAppComponent getAppComponent() {
        return  DaggerBaseAppComponent.builder()
                .appModule(new AppModule(this))
                .retrofitModule(new RetrofitModule(this))
                .build();
    }

}

这时候就体现了上面说道的Component和Module放置位置的重要性。 我们的module 和APPComponent都是放在底层Library

  1. BaseActivity的封装。这个我感觉比较灵活,自己根据自己的项目来进行封装,怎么样都行。给大家看一下我的代码,我是这样的
public abstract class BaseMvpActivity<T extends BasePresenter> extends AppCompatActivity implements BaseView {
    @Inject
    protected T mPresenter;
    public static Activity mContext;
    private Unbinder mUnBinder;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(initLayout());
        mContext = this;
        mUnBinder = ButterKnife.bind(this);
        initInject();
        if (mPresenter != null) {
            mPresenter.attachView(this);
        }
        initData();
    }


    protected abstract void initInject();


    protected ActivityComponent getActivityComponent() {
        return DaggerActivityComponent
                .builder()
                .baseAppComponent(BaseApp.getInstance().getAppComponent())
                .activityModule(getActivityModule())
                .build();
    }

    protected ActivityModule getActivityModule() {
        return new ActivityModule(this);
    }

    /**
     * 初始化布局
     */
    public abstract int initLayout();


    /**
     * 初始化数据
     */
    public abstract void initData();


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mPresenter != null)
            mPresenter.detachView();
        mUnBinder.unbind();
    }


}


没什么亮点啥的,就是简单的封装,我这项目是基于组件化+MVP开发的,可能你看到了Presenter这些东西。

总结

其实主要的东西还是讲解如何在组件化开发中配置Dagger 让你更省时更省力,节省代码量和错误量。绕过很多坑

ending

上面可能有说不明白的,可以直接评论中@我,我会及时回应,或者有说哪里不正确的有优化的地方都可以@我,欢迎讨论,如果这篇文章反应比较好的话,打算出一篇组件化架构+MVP架构混合开发。希望文章带来的是收获而非时间的浪费,谢谢大家的支持

日记本