当前位置: 首页 > 知识库问答 >
问题:

MVVM-当应用程序关闭时,从通知开始访问BroadcastReceiver中的ViewModel/SQLite

饶明亮
2023-03-14

我有一个提醒通知,每隔几天发送一次。

该通知的发送是由重复的AWRMManager触发的。通知本身内置在我的BroadcastRecectoronRecture中(如这里所述)。因此,当触发onRecture时,应用程序甚至没有打开/运行。

现在,我想访问我的(本地)SQLite数据库,并获取用于构建通知的正确内容,但我如何在这里获得一个ViewModelProvider(代码中的xxx)来访问我的ViewModel

public void onReceive(Context context, Intent intent) {    

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

    //do stuff
}

或者问一个更好的问题,这是好的做法吗?
另一种可能性是填充PendingIntent中的所有内容,这将触发onRecture,所以我可以在收到后一个接一个地检索它。但这将更加困难,因为它是一个重复的警报,每次需要不同的内容,但只被触发一次。

我查看了一些搜索结果,但它们并没有解决我的问题:

  • Android上自定义视图的MVVM体系结构
    -

正在读取ViewModel之外的LiveData[…],据说

如果应用程序的一部分不影响用户界面,那么您可能不需要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惯例吗?
我应该使用其他架构吗?现在对我来说这似乎是有意义的,因为这是我只检索一次的东西,不需要观察变化。

共有2个答案

冯风史
2023-03-14

如果问题是读取SQLite DB,则不需要ViewModel。问题可能是无法直接调用挂起函数(viewmodelscope.launch{}),但有一个简单的修复方法:runBlocking。

我假设Broadcast接收机已经在后台,所以没有必要启动后台协程。

runBlocking {
   val reminders = favoriteDao.queryAllReminders()
   reminders.forEach { reminder ->
       Log.i("Reminder", reminder.info)
   }
}
益思博
2023-03-14

在这种情况下,ViewModel的真正用途是什么
它会将您的数据转换为某种方便查看的格式
它会处理数据更新吗?(我的意思是,会有数据更新吗?好像你在一段时间内有一个通知)
或者它会把干净的同步代码弄得杂乱无章,使其异步化,而没有真正的目的?

如果您仅对最后一个问题回答“是”,则此处可能不需要ViewModel:)是否需要其他体系结构?不,你不需要架构。你需要显示一个通知,所以就这么做吧!

如果你是一个真正的MVVM迷,你仍然可以通过
首先,删除ViewModelProviders。因为这里无法使用。它需要活动或片段,而你两者都没有。ViewModelProvider的目的是在重新创建活动/片段时向您提供相同的viewmodel实例—这显然不是您的情况
其次,自己构造viewmodel:newnotificationViewModel()
第三,从viewmodel而不是livedata返回普通对象,因为您的数据不是活动的。

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

请注意,您甚至不需要扩展ViewModel类,因为您不使用ViewModelProviders。

 类似资料:
  • 当应用程序完全关闭时,如何以编程方式发送通知? 示例:用户关闭应用程序,也在Android Taskmanager中,然后等待。应用程序应在X秒后或应用程序检查更新时发送通知。 我试图使用这些代码示例,但是: 应用程序关闭时推送通知-活动太多/无法工作 我如何让我的应用程序在关闭时发送通知很多信息,但我不知道如何处理 当android应用程序关闭时,如何发送本地通知?-很多信息,但我不知道如何处理

  • Firebase push在某些设备上不起作用,当应用程序关闭时只有数据负载。请参阅以下线程:https://github.com/firebase/quickstart-android/issues/41 我知道当应用程序被swipe杀死时,一些OEM会杀死应用程序的所有服务,这些服务直接影响FirebbaseMessagingService并且由于这个onMessageReceived()方法

  • 我想用Xamarin格式的C#创建一个基于文本的Android游戏。 在故事中,我想设置角色任务,这需要一些时间,例如“我去挖这个洞,完成后给你打电话。” 如何将通知设置为在设置的时间之后显示?例如,上述声明可能需要10分钟,然后用户收到继续游戏的通知? 我一周前才开始做C#,所以如果这是noobish,或者已经被问到了,我道歉。我到处都找过,但有几种类型的通知,当我试图理解它时,似乎我在读法语。

  • 我的任务是设置警报,以触发接收器在特定时间显示通知。 如果应用程序是打开的或只是在后台,代码就可以完美地工作。 在应用程序被杀死时,当执行警报时仍然可以触发接收器。 但是,没有显示通知。 我能做什么? 报警功能: 报警接收器 显示xml

  • 仅当应用程序关闭时,数据有效负载的使用不会收到任何通知,并且不会触发消息接收方法。 在下图中显示数据负载,单击此处查看参数 回复是点击这里查看回复 响应成功1,但在redmi手机中未收到任何通知。

  • 我目前正在开发Android(Cordova)应用程序,我正在使用Oneignal推送通知。首先,如果我关闭应用程序,推送通知不会被传递,所以我不得不添加一个Cordova插件来保持我的应用程序在后台运行: 我在deviceready之后的代码: 谢了。