MVVM - доступ к ViewModel в BroadcastReceiver начался с уведомления о закрытии приложения - PullRequest
1 голос
/ 12 мая 2019

У меня есть напоминание, которое отправляется каждые несколько дней.

Отправка этого уведомления запускается с повторением AlarmManager.Само уведомление встроено в onReceive моего BroadcastReceiver (как описано здесь ).Поэтому, когда onReceive запущен, приложение даже не открывается / не работает.

Теперь в этот момент Я хочу получить доступ к моей (локальной) базе данных sqllight и получить правильный контент для сборкиуведомление с, но как я могу получить ViewModelProvider (ххх в коде) в этом месте, чтобы даже получить доступ к моему ViewModel?

public void onReceive(Context context, Intent intent) {    

    NotificationViewModel viewModel = 
    ViewModelProviders.of(XXX).get(NotificationViewModel.class);

    //do stuff
}

Или задать лучший вопрос, это даже хорошопотренироваться?
Другой возможностью было бы вставить весь контент в PendingIntent, который вызовет onReceive, так что я мог бы получить его один за другим, получив один раз.Но это было бы еще сложнее, так как это повторяющийся сигнал тревоги, и каждый раз ему нужно другое содержание, но оно вызывается только один раз.


Я просмотрел несколько результатов поиска, но они не решили мою проблему:

  • Архитектура MVVM для пользовательских представлений на Android
    -> Похоже, много кода для такой незначительной проблемы, плюс Kotlin, что трудно понять для меня
  • Работа с BroadcastReceivers с использованием шаблона проектирования Presenter Model Viewer
    -> Здесь кажется, что сначала необходимо настроить несколько вещей в действиях, прежде чем они смогут дажеиспользуйте его, но мне нужно запустить этот код без запуска моего приложения
  • Доступ к BroadCastReceiver в Viewmodel
    -> Это похоже на то, что мне нужно , но это также требует предварительной настройки до.Я хотел попробовать это, но мне нужно было бы вручную создать мою MainActivity для доступа к таким переменным.Разве это не открыло бы новое действие на устройстве пользователя без предупреждения?
    Возможно ли вообще получить доступ к моей базе данных без того, чтобы мое приложение находилось на переднем плане?

Редактировать:

Чтение LiveData за пределами ViewModel [...] , говорится

Есличасть вашего приложения не влияет на пользовательский интерфейс, вероятно, вам не нужны LiveData.

Так что это означает, что я должен просто получить доступ к своему хранилищу с контекстом и извлечь из него необработанные данные, без оболочки LiveData?

Итак

public void onReceive(Context context, Intent intent) {

    NotificationRepository rp = new NotificationRepository(context);
    MessageNotification notification = rp.getNextNotification();
}

вместо

public void onReceive(Context context, Intent intent) {

    NotificationViewModel viewModel = 
    ViewModelProviders.of(XXX).get(NotificationViewModel.class);
    MessageNotification notification = 
    viewModel.getNextNotification().observe(XXX, new 
         Observer<MessageNotification>() {
            @Override
            public void onChanged(MessageNotification messageNotification) {
                //do stuff
            }
         });
}

Но идет ли это вразрез с соглашением MVVM?
Следует лиЯ использую какую-то другую архитектуру?Сейчас мне кажется, что это имеет смысл, поскольку это то, что я извлекаю только один раз, и мне не нужно наблюдать за изменениями.

1 Ответ

1 голос
/ 18 мая 2019

Какова реальная цель ViewModel в этой ситуации?
Будет ли он преобразовывать ваши данные в какой-то удобный для просмотра формат?
Будет ли он обрабатывать обновления данных?(Я имею в виду, будут ли когда-нибудь обновления данных? Кажется, у вас есть какое-то время от времени уведомление)
Или это просто загромождает чистый, синхронный код и делает его асинхронным без реальной цели?

Если вы ответите «да» только на последний вопрос, вам, вероятно, здесь не нужна ViewModel :) Вам нужна другая архитектура?Нет, вам не нужна архитектура.Вам нужно отобразить уведомление, так что просто сделайте это!


Если вы настоящий фанат MVVM, вы все равно можете пройти.
Во-первых, отбросьте ViewModelProviders.of, потому что здесь невозможно использовать,Требуется активность или фрагмент, и у вас нет ни одного из них.Цель ViewModelProvider - предоставить вам тот же экземпляр модели представления, когда действие / фрагмент воссоздан - это явно НЕ ваш случай.
Во-вторых, создайте модель представления самостоятельно: new NotificationViewModel().
В-третьих, верните обычный объект из вашей модели представления.вместо liveata, потому что ваши данные не живут.

public class NotificationViewModel {
    MessageNotification getNextNotification() {
        // ...
    }
}

Обратите внимание, что вам даже не нужно расширять класс ViewModel, так как вы не используете ViewModelProviders.

...