多模块中带有 Dagger 2 的 Android Room

发布于 2025-01-19 05:32:34 字数 2126 浏览 4 评论 0原文

有没有一种方法或方法可以从模块/库提供可以在任何项目(应用程序模块)上使用的 Room DB 实例?

我面临的问题是扩展 RoomDatabase() 的抽象类位于我们的应用程序模块中,我们使用 @Database 注释定义我们的实体。这就是我无法提供来自应用程序模块以外的模块的 Room 实例的原因,因为创建 Room 实例需要您定义扩展 RoomDataBase() 的应用程序数据库类。

我的 :app:libs:common 模块中的示例。这是一个子模块,它有自己的存储库,可用于任何项目。 appNameAppModule 中提供,它驻留在应用程序模块本身中,并且与我创建的 SharedPreferences 一起使用。

 @Module
 CommonModule {
    
    @Provides
    @Singleton
    fun provideSharedPreferencesInstance(
        @Named("AppName") appName: String,
        application: Application
    ): SharedPreferences {
        application.apply {
            return getSharedPreferences(appName, MODE_PRIVATE)
        }
    }

    @Provides
    @Singleton
    fun provideAppSharedPrefImplInstance(
        sharedPreferences: SharedPreferences
    ): SharedPref = SharedPrefImpl(sharedPreferences)

    @Provides
    @Singleton
    fun provideRoomDatabaseInstance(
            application: Application,
            @Named("AppName") appName: String,
            @Named("AppDatabase") roomDatabase: RoomDatabase
        ): RoomDatabase {
            return Room
                .databaseBuilder(application, roomDatabase.javaClass, appName)
                .fallbackToDestructiveMigration()
                .build()
        }
    
}

这是应用程序模块。

@Module
object AppModule {
    @Provides
    @Singleton
    @Named("AppName")
    fun provideAppName(application: Application): String {
        application.apply {
            return getString(R.string.app_name)
        }
    }

    @Provides
    @Singleton
    fun provideAssetDao(@Named("AppDatabase") db: AppDatabase): AssetDao {
        return db.assetDao
    }
}

由于我们在扩展 RoomDatabase() 时使用抽象类,在本例中它是 AppDatabase 我尝试使用 @Binds 希望它能够工作。

@Module
abstract class RoomModule {

    @Binds
    @Singleton
    @Named("AppDatabase")
    abstract fun bindAppDatabase(appDatabase: AppDatabase): AppDatabase

}

我认为能够通过通用模块上的通用提供 AppDatabase 类将允许我解决这个问题

Is there a way or approach to provide a Room DB instance from a module/library which can be consume on any project (app module)?

The problem I am facing is the abstract class that extends RoomDatabase() lies in our app module and there we define our entities using @Database annotation. This is the reason I cannot provide a Room instance coming from a module other than app module since creating Room instance requires you to define the app database class that extends the RoomDataBase().

Example in my :app:libs:common module. This is a submodule, it has its own repository which can be use for any project. The appName is provided in the AppModule which resides in app module itself and it is working with SharedPreferences that I made.

 @Module
 CommonModule {
    
    @Provides
    @Singleton
    fun provideSharedPreferencesInstance(
        @Named("AppName") appName: String,
        application: Application
    ): SharedPreferences {
        application.apply {
            return getSharedPreferences(appName, MODE_PRIVATE)
        }
    }

    @Provides
    @Singleton
    fun provideAppSharedPrefImplInstance(
        sharedPreferences: SharedPreferences
    ): SharedPref = SharedPrefImpl(sharedPreferences)

    @Provides
    @Singleton
    fun provideRoomDatabaseInstance(
            application: Application,
            @Named("AppName") appName: String,
            @Named("AppDatabase") roomDatabase: RoomDatabase
        ): RoomDatabase {
            return Room
                .databaseBuilder(application, roomDatabase.javaClass, appName)
                .fallbackToDestructiveMigration()
                .build()
        }
    
}

This is the app module.

@Module
object AppModule {
    @Provides
    @Singleton
    @Named("AppName")
    fun provideAppName(application: Application): String {
        application.apply {
            return getString(R.string.app_name)
        }
    }

    @Provides
    @Singleton
    fun provideAssetDao(@Named("AppDatabase") db: AppDatabase): AssetDao {
        return db.assetDao
    }
}

Since we use abstract class when extending RoomDatabase() in this case it's AppDatabase I tried to use @Binds in hope that it will work.

@Module
abstract class RoomModule {

    @Binds
    @Singleton
    @Named("AppDatabase")
    abstract fun bindAppDatabase(appDatabase: AppDatabase): AppDatabase

}

I think being able to provide the AppDatabase class via generic on common module will allow me to fix this issue

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

守望孤独 2025-01-26 05:32:34

我就遇到过这种情况。
我编写了一个在 Android 项目中使用多个模块的样板,它包含房间数据库。
你可以参考我的repo
我的仓库

希望这对您有帮助

I have encountered this case.
I have written a boilerplate for using multiple modules in an Android project, it contains the room database.
You can refer to my repos
My Repo

Hope this is helpful to you

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文