android - 使用 Dagger2 的项目结构
问题描述
我正在学习如何使用Dagger2和MVP,所以我创建了项目,包含一个主要活动viewPager
和两个片段。
代码正在运行,但我认为我在创建 Dagger 类时做错了。我想如果我继续,创造一个怪物=)
我请你帮忙评论我的代码架构,与 Dagger2 相关联。也许这个问题应该在 CodeReview 上:如果是这样,我删除并移动它。
好的,我一步一步地展示它。主要怀疑步骤 3 中的错误代码。
首先,主要活动称为HomeActivity
,片段(我展示一个)称为HomePacksFragment
。关于动物的应用程序,以及它们的片段展示包,这就是它为什么这么叫的原因。
1)我有两个模块: ,为和PresentersModule
提供演示者:HomeActivity
HomePacksFragment
@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);
}
}
我做正确的事情还是我必须改变一些事情,直到为时不晚?
升级版:
好的,我用谷歌搜索了简单的 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;
}
它看起来比我的更好更干净,但我有一个问题。在这个例子中我们总是 retutn basicComponent,所以这意味着它必须包含所有模块?创建“上帝”组件是正常做法吗?=)
如果我有 3 个模块,我需要编写(例如):
appComponent = DaggerAppComponent
.builder()
.appModule(appModule)
.presentersModule(new PresentersModule())
.roomModule(new RoomModule(this))
.build();
解决方案
根据我的想法和您所说的参考资料,您正在以一种不好的方式使用 AnimalsLibraryApp。在应用程序类中,您只需要声明一个匕首组件,然后在每个视图中,您将在视图中注入带有该组件的模块。如果你用谷歌搜索一个 dagger2 示例并检查扩展应用程序的类,你就会明白。
推荐阅读
- java - 我的情况无法正常工作我的应用程序在单击按钮时崩溃
- python - 在 alpine 3.9 上设置 mitmproxy 时出错
- powershell - 在 WinRM 中将 IP 地址范围添加到受信任的主机
- bash - 多个 if 和 read 行被忽略
- c# - 使用 C# 的 mysql 数据创建 Json 文件
- start-job - 如何在 start-job 中使用 -InitializationScript 中的 2 个以上函数
- javascript - 在任意 HTML 结构中使用正则表达式包装展开的 textNode
- javascript - 在 JSON 中存储一个对象以在 NgxData-Table 中输出
- android - 如何在 WebView 中更新请求标头
- angular - 从 Angular HttpClient 使用 Spring Boot StreamingResponseBody