База данных Singleton Room в SyncAdapter для запуска LiveData

Я изо всех сил пытаюсь использовать Room как singleton в моем SyncAdapter . Я использую Котлин.

Класс моей комнаты

 @Database(entities = [(Product::class)], version = 1, exportSchema = false) abstract class AppDatabase : RoomDatabase() { abstract fun productDao(): ProductDao companion object { @Volatile private var INSTANCE: AppDatabase? = null fun getInstance(context: Context) : AppDatabase = INSTANCE ?: synchronized(this) { INSTANCE ?: buildDatabase(context.applicationContext) .also {INSTANCE = it} } private fun buildDatabase(context: Context) = Room .databaseBuilder(context.applicationContext, AppDatabase::class.java, "database.db") .allowMainThreadQueries() .build() } } 

Я извлекаю экземпляр базы данных, как это

 val db = AppDatabase.getInstance(applicationContext) 

И моя проблема в том, что я всегда получаю два разных экземпляра AppDatabase в своих действиях и SyncAdapter . Хотя среди объектов AppDatabase объект действительно singleton .AppDatabase_Impl@3c9ff34d , а для каждого onPerformSync () AppDatabase тоже singleton .AppDatabase_Impl@7d7718d . Но, как вы видите, это два разных объекта. Может ли кто-нибудь объяснить, что я здесь пропущу?

С другой стороны, возможно, я концептуально ошибаюсь в том, чего я пытаюсь достичь. Тогда любой совет будет оценен.

Дело в том, чтобы использовать LiveData для обновления компонентов пользовательского интерфейса, когда новые данные вставляются с удаленного сервера через SynAdapter . В этом случае я должен использовать тот же объект productDao в ViewModel/Activity и в SyncAdapter , чтобы запускать LiveData при вставке новых продуктов, иначе он не будет запущен. Итак, чтобы получить тот же productDao я должен получить тот же (то есть singleton) AppDatabase .

Я знаю, что это может быть реализовано с помощью ContentProvider , который запускается автоматически при вставке новых данных. Но я действительно хочу попробовать новые компоненты архитектуры Android. Или, может быть, использование ContentProvider – единственный правильный способ реализовать этот прецедент?

    Если вам нужна легкая связь между различными Threads вам нужно быть в одном процессе.

    В AndroidManifest.xml вы можете указать атрибут android:process=":processName" можно использовать для операций, служб (которые относятся к SyncAdapters), поставщиков контента и широковещательных приемников , которые могут помочь вам превысить пределы по умолчанию для кучи (памяти) для одного процесса.

    Это обобщенные PRO / CONS:

    Multi-process PRO: у вас больше памяти для запуска вашего приложения, и если процесс выходит из строя, это не приводит к сбою других.

    Multi-process CONS: намного сложнее (но не невозможно), чтобы процессы взаимодействовали друг с другом, но, очевидно, вы не можете делиться между ними состоянием (в вашем случае это состояние является singleton)

    Для глубокого понимания вы должны прочитать эту статью и этот хороший ответ

    Мое предложение : если ваше приложение не так сложно, и у вас нет проблем с памятью, я предлагаю вам начать с единого процесса. Если вы хотите отделить SyncAdapter, который обновляет ваши данные из приложения или в какой-то момент разработки вы обнаружите узкие места или сбои, связанные с одним процессом, вы должны переключиться на мультипроцесс, удалить прямую LiveData и использовать ContentProvider для передавать данные.

    Использование dagger2:

     class MyApplication : Application(){ val component: AppComponent by lazy { DaggerAppComponent.builder().appModule(AppModule(this)).build() } @Inject lateinit var database : AppDatabase override fun onCreate() { super.onCreate() component.inject(this) } } @Singleton @Component(modules = arrayOf( AppModule::class )) interface AppComponent { fun inject(app: MyApplication) } @Module class AppModule constructor(private val context: Context) { @Provides @Singleton fun providesDatabase() = Room.databaseBuilder(context, AppDatabase::class.java, "mydb.db").build() } 

    От деятельности:

     @Inject lateinit var mRoomDatabase: AppDatabase override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) (application as MyApplication).component.inject(this) } 
    Intereting Posts
    Не удается найти вид в нижнем листе с эспрессо Изменить текучесть <Список <Obj1 >> в текущую <Список <Obj2 >> в комнате Не удается получить dokka для генерации котлинских документов по проекту gradle / android Как заставить Джексона использовать параметры по умолчанию для Kotlin для отсутствующих значений? NoClassDefFoundError okhttp3.internal.io.FileSystem Свойство getter напечатано на Supertype вместо внедрения в Kotlin Andoird anko DSL – добавление текстовых просмотров и создание их «новой строки», когда нет больше ширины экрана? Android: Как настроить гравитацию плавающей кнопки действия программно? автономный сценарист, чтобы получить intellij проект Kotlin JS Переопределение «внешней» функции с необязательными параметрами Конвертировать приложение Kotlin для Android с помощью Project Astoria Аномалии покрытия кода в Android (Kotlin) Ошибка встроенной функции компилятора Kotlin, не совсем уверенная, что происходит Можете ли вы иметь общий основной конструктор в Котлин? Android: невозможно обновить Listview с помощью CustomAdapter