У меня есть приложение для Android, которое использует базу данных комнат и кинжал. Я перепробовал все ответы, которые нашел в Интернете, и это мое последнее средство, поскольку я решаю эту проблему уже вторую неделю.
Моя установка:
com.example.app
|-configurations
|-AppComponent.kt
|-AppDB.kt
|-AppModule.kt
|-MyApp.kt
@Singleton
@Component(modules = [AppModule::class])
interface AppComponent {
fun inject(baseViewModel: BaseViewModel)
}
@Database(entities = [
User::class
], version = 1, exportSchema = true)
abstract class AppDB : RoomDatabase() {
abstract fun userRepository(): IUserRepository
companion object{
@Volatile
private var db_instance: AppDB? = null
@Synchronized
fun getAppDBInstance(context : Context): AppDB {
return db_instance ?: synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
AppDB::class.java,
"TransitPayDB.db3"
).allowMainThreadQueries()
.build()
db_instance = instance
instance
}
}
}
}
class MyApp: Application() {
private lateinit var appComponent: AppComponent
override fun onCreate() {
super.onCreate()
appComponent = DaggerAppComponent.builder().appModule(AppModule(this)).build()
}
fun getAppComponent(): AppComponent {
return appComponent
}
}
@Module
class AppModule(private val application: Application) {
@Singleton
@Provides
fun getUserRepo(appDB: AppDB): IUserRepository {
return appDB.userRepository()
}
@Singleton
@Provides
fun getRoomDBInstance(context: Context): AppDB {
return AppDB.getAppDBInstance(context)
}
@Singleton
@Provides
fun provideAppContext(): Context {
return application.applicationContext
}
}
И в своем Манифесте я добавил это:
android:name = ".configurations.MyApp"
У меня нормальная транзакция, когда телефон отключен от отладчика. а также я могу видеть базы данных и данные во время отладки. но моя проблема в том, что когда я снова нажимаю «Отладка», все данные исчезают, и мне приходится снова заполнять все тестовые данные.
что-то не так с моими конфигурациями?
кстати, вот как я внедряю свои репозитории:
open class BaseViewModel(application: Application) : AndroidViewModel(application) {
@Inject lateinit var userRepository: IUserRepository
init {
(application as MyApp).getAppComponent().inject(this)
sharedUserId = sharedPrefs.getInt("userId",0)
sharedCompanyId = sharedPrefs.getInt("companyId",0)
sharedRoleId = sharedPrefs.getInt("roleId",0)
sharedFullName = sharedPrefs.getString("fullName","")
sharedApiToken = sharedPrefs.getString("apiToken","")
}
}
Заранее спасибо.
Не имеет отношения к вашей проблеме, но ваша функция получения синглтона имеет недостаток (тот же недостаток, что и в Google Room With a View CodeLab). Внутри синхронизированного блока вам необходимо выполнить вторую проверку на то, имеет ли свойство резервного копирования значение null, и вернуть его, если это не так, прежде чем приступить к созданию экземпляра.
Как вы определяете, что данные пропали?
@IvanWooll, каждый раз, когда я проверяю базу данных сразу после запуска приложения. все данные пропали.
@Левиафан, я использую Кинжал, а не Кинжал-Эфес.
@ Tenfour04, не могли бы вы указать мне правильный путь, сэр?
@jreloz В образцах, которые вы предоставили в своем вопросе, нет ничего выдающегося. Вот руководство по настройке Hilt в проекте: Developer.android.com/training/dependent-injection/… Как только вы поймете, как использовать hilt для предоставления зависимостей, я рекомендую вам взглянуть на следующее: разработчик .android.com/training/data-storage/room Удачи.
Первая строка внутри синхронизированного блока должна быть db_instance?.let { return it }
В противном случае любой поток, который вызывает эту функцию после первого вызывающего объекта, но вынужден ждать блока синхронизации, создаст дубликат экземпляра, который заменит предыдущий экземпляр.
Ладно, это ошибка новичка.
У меня установлен флажок «Очистить хранилище приложения перед развертыванием». Его необходимо снять, чтобы студия Android не очищала хранилище приложений.
Чтобы уточнить, вы используете напрямую Dagger, а не Hilt (который построен на основе Dagger и оптимизирован для Android)?