Dagger2的项目结构

时间:2019-03-02 12:23:35

标签: android dagger-2

我正在学习如何使用 Dagger2 MVP ,因此我创建了项目,其中包含一个主要活动,其中包含viewPager和两个片段。

代码正在工作,但是我认为在创建Dagger类时我做错了什么。我想,如果我很幸运,那就创建一个怪物=)

我想请您帮我评论与Dagger2相关的代码体系结构。也许这个问题应该在CodeReview上:如果是这样,我删除并移动它。

好吧,我一步一步地展示它。主要怀疑步骤3上的错误代码。

首先,主要活动称为HomeActivity,而片段(我显示一个)称为HomePacksFragment。关于动物的应用程序,以及片段展示的动物包装,这就是为什么要这样称呼。

1)我有两个模块:PresentersModule,为HomeActivityHomePacksFragment提供演示者:

@Module
public class PresentersModule {
    @Provides
    HomePresenter provideHomePresenter(AnimalDatabase animalDatabase) {
        return new HomePresenter(animalDatabase);
    }

    @Provides
    HomePacksFragmentPresenter provideHomePacksFragmentPresenter(AnimalDatabase animalDatabase) {
        return new HomePacksFragmentPresenter(animalDatabase);
    }
}

RoomModule可以访问数据库和DAO:

@Module
public class RoomModule {
    private AnimalDatabase db;

    public RoomModule(Application mApplication) {
        db = Room.databaseBuilder(mApplication,
                AnimalDatabase.class, AnimalDatabase.DATABASE_NAME)
                .allowMainThreadQueries()
                .fallbackToDestructiveMigration()
                .build();
    }

    @Singleton
    @Provides
    AnimalDatabase providesRoomDatabase() {
        return db;
    }

    @Singleton
    @Provides
    DAO providesProductDao(AnimalDatabase db) {
        return db.daoAccess();
    }
}

2)然后,我有了组件AppComponent,该组件知道我所有的模块,可以在具体视图中注入依赖项:

@Singleton
@Component(modules = {PresentersModule.class, RoomModule.class})
public interface AppComponent {
    void injectsHomeActivity(HomeActivity homeActivity);
    void injectsHomePacksFragment(HomePacksFragment homePacksFragment);

    DAO animalDao();
    AnimalDatabase animalDatabase();
}

3)然后我将AnimalsLibraryApp类扩展为Application,这是我认为错误的地方。

public class AnimalsLibraryApp extends Application {
    private static AnimalsLibraryApp instance;
    private static AppComponent homeActivityComponent;
    private static AppComponent homeFragmentPacksComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;

        if (BuildConfig.DEBUG) {
            Timber.plant(new Timber.DebugTree());
        }
        createHomeActivityComponent();
        createHomePacksComponent();
    }

    public static AnimalsLibraryApp getInstance() {
        return instance;
    }

    public static AppComponent getHomeActivityComponent() {
        return homeActivityComponent;
    }

    public static AppComponent getHomeFragmentPacksComponent() {
        return homeFragmentPacksComponent;
    }

    private void createHomeActivityComponent() {
        homeActivityComponent = DaggerAppComponent.builder()
                .presentersModule(new PresentersModule())
                .roomModule(new RoomModule(instance))
                .build();
    }

    private void createHomePacksComponent() {
        homeFragmentPacksComponent = DaggerAppComponent.builder()
                .presentersModule(new PresentersModule())
                .roomModule(new RoomModule(instance))
                .build();
    }
}

此类的想法是提供AppComponent的单例。从技术上讲,它可行,但是如果我有10或20个视图怎么办?扩展的Application类是基本类,它将不仅仅包含AppComponent创建逻辑,因此这里将有更多内容。我写得对吗?

4)结束了。我创建了HomeActivity,并通过简单(不是吗)行注入了依赖关系。

public class HomeActivity extends AppCompatActivity implements HomeContract.View {
    @Inject
    HomePresenter presenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        AnimalsLibraryApp.getHomeActivityComponent().injectsHomeActivity(this);

        presenter.attachView(this);
        presenter.viewIsReady();

        DatabaseUtils.copyDatabase(this, AnimalDatabase.DATABASE_NAME);

        ViewPager viewPager = findViewById(R.id.pager);

        HomeMenuAdapter myPagerAdapter = new HomeMenuAdapter(getSupportFragmentManager());
        viewPager.setAdapter(myPagerAdapter);
        TabLayout tabLayout = findViewById(R.id.tablayout);
        tabLayout.setupWithViewPager(viewPager);

        tabLayout.getTabAt(0).setIcon(R.drawable.help);
        tabLayout.getTabAt(1).setIcon(R.drawable.help);
    }
}

我做正确的事,还是必须改变一些,直到还不晚呢?

UPD:

好吧,我用Google搜索了简单的Dagger 2示例,发现了这个App类版本:

public class MyApp extends Application {
    private static MyApp app;
    private AppModule appModule;
    private BasicComponent basicComponent;

    @Override
    public void onCreate() {
        super.onCreate();
        app = this;

        appModule = new AppModule(this);
        basicComponent = DaggerBasicComponent.builder()
                .appModule(appModule)
                .build();
    }

    public static MyApp app() {
        return app;
    }

    public AppModule appModule() {
        return appModule;
    }

    public BasicComponent basicComponent() {
        return basicComponent;
    }

看起来比我的更好更干净,但是我有一个问题。在此示例中,我们始终撤消basicComponent,这意味着它必须包含所有模块吗?创建“神”组件是正常的做法? =)

如果我有3个模块,则需要编写(例如):

appComponent = DaggerAppComponent
                .builder()
                .appModule(appModule)
                .presentersModule(new PresentersModule())
                .roomModule(new RoomModule(this))
                .build();

1 个答案:

答案 0 :(得分:1)

根据我的想法和您所说的参考,您以不良方式使用AnimalsLibraryApp 在应用程序类中,您只需要声明一个匕首组件,然后在每个视图中将在该视图中注入带有该组件的模块 如果您用dagger2示例搜索Google并检查扩展应用程序的类,您将了解