MVVM - 在应用程序关闭时从通知开始访问 BroadcastReceiver 中的 ViewModel/SQLite
MVVM - Accessing ViewModel/SQLite in a BroadcastReceiver started from a notification when app is closed
我有一个每隔几天发送的提醒通知。
该通知的发送是通过重复 AlarmManager
触发的。通知本身内置于我的 BroadcastReceiver
的 onReceive
中(如 所述)。所以当onReceive
被触发时,app连open/running.
现在 我想访问我的(本地)SQLite 数据库 并获取正确的内容来构建通知,但我如何获得 ViewModelProvider
(代码中的 xxx)在这个地方甚至可以访问我的 ViewModel
?
public void onReceive(Context context, Intent intent) {
NotificationViewModel viewModel =
ViewModelProviders.of(XXX).get(NotificationViewModel.class);
//do stuff
}
或者问一个更好的问题,这是好的做法吗?
另一种可能性是将触发 onReceive
的 PendingIntent
中的所有内容都填满,这样我就可以在收到后一个一个地检索它。但这会更难,因为它是一个重复的警报,每次都需要不同的内容,但只触发一次。
我查看了一些搜索结果,但它们没有解决我的问题:
- MVVM Architecture for Custom Views on Android
-> 对于这样一个小问题,似乎有很多代码,再加上是 Kotlin,这对我来说很难理解
- Dealing with BroadcastReceivers using the Model View Presenter design pattern
-> 这里似乎有必要先在活动中设置一些东西,然后才能使用它,但我需要在没有我的应用程序的情况下启动这段代码 运行
-> 这似乎是最接近我需要的,但它也需要之前的设置。我想试试这个,但我需要手动创建我的 MainActivity 来访问它的变量。这不会在没有警告的情况下在用户设备上打开一个新的 activity 吗?
甚至可以在我的应用程序不在前台的情况下访问我的数据库吗?
编辑:
正在阅读LiveData beyond the ViewModel [...],据说
If part of your app doesn’t affect the UI, you probably don’t need 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 约定?
我应该使用其他架构吗?现在这对我来说似乎很有意义,因为它是我只检索一次而不必观察变化的东西。
在这种情况下 ViewModel 的真正目的是什么?
它会将您的数据转换为某种 view-convenient 格式吗?
它会处理数据更新吗? (我的意思是,会不会有数据更新?好像你有一段时间有一个通知)
或者它只会让干净的同步代码变得杂乱无章,并使其变得毫无意义?
如果你只对最后一个问题回答 'yes',你可能不需要这里的 ViewModel:)
您需要其他架构吗?不,你不需要架构。您需要显示一个通知,那就去做吧!
如果你是真正的MVVM粉丝,你还是可以通过的。
首先,删除 ViewModelProviders.of
因为它不可能在这里使用。它需要 activity 或片段,而你两者都没有。 ViewModelProvider 的目的是在重新创建 activity/fragment 时为您提供相同的视图模型实例 - 这显然不是您的情况。
其次,自己构建viewmodel:new NotificationViewModel()
.
第三,return 来自您的视图模型的普通对象而不是实时数据,因为您的数据不是实时的。
public class NotificationViewModel {
MessageNotification getNextNotification() {
// ...
}
}
请注意,您甚至不需要扩展 ViewModel
class,因为您不使用 ViewModelProviders。
如果问题是读取 SQLite 数据库,则不需要 ViewModel。问题可能是无法直接调用挂起函数 (viewmodelscope.launch{}),但有一个简单的解决方法:runBlocking。
我假设 Broadcastreceiver 已经在后台,所以不需要启动后台协程。
runBlocking {
val reminders = favoriteDao.queryAllReminders()
reminders.forEach { reminder ->
Log.i("Reminder", reminder.info)
}
}
我有一个每隔几天发送的提醒通知。
该通知的发送是通过重复 AlarmManager
触发的。通知本身内置于我的 BroadcastReceiver
的 onReceive
中(如 onReceive
被触发时,app连open/running.
现在 我想访问我的(本地)SQLite 数据库 并获取正确的内容来构建通知,但我如何获得 ViewModelProvider
(代码中的 xxx)在这个地方甚至可以访问我的 ViewModel
?
public void onReceive(Context context, Intent intent) {
NotificationViewModel viewModel =
ViewModelProviders.of(XXX).get(NotificationViewModel.class);
//do stuff
}
或者问一个更好的问题,这是好的做法吗?
另一种可能性是将触发 onReceive
的 PendingIntent
中的所有内容都填满,这样我就可以在收到后一个一个地检索它。但这会更难,因为它是一个重复的警报,每次都需要不同的内容,但只触发一次。
我查看了一些搜索结果,但它们没有解决我的问题:
- MVVM Architecture for Custom Views on Android
-> 对于这样一个小问题,似乎有很多代码,再加上是 Kotlin,这对我来说很难理解 - Dealing with BroadcastReceivers using the Model View Presenter design pattern
-> 这里似乎有必要先在活动中设置一些东西,然后才能使用它,但我需要在没有我的应用程序的情况下启动这段代码 运行
-> 这似乎是最接近我需要的,但它也需要之前的设置。我想试试这个,但我需要手动创建我的 MainActivity 来访问它的变量。这不会在没有警告的情况下在用户设备上打开一个新的 activity 吗?
甚至可以在我的应用程序不在前台的情况下访问我的数据库吗?
编辑:
正在阅读LiveData beyond the ViewModel [...],据说
If part of your app doesn’t affect the UI, you probably don’t need 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 约定?
我应该使用其他架构吗?现在这对我来说似乎很有意义,因为它是我只检索一次而不必观察变化的东西。
在这种情况下 ViewModel 的真正目的是什么?
它会将您的数据转换为某种 view-convenient 格式吗?
它会处理数据更新吗? (我的意思是,会不会有数据更新?好像你有一段时间有一个通知)
或者它只会让干净的同步代码变得杂乱无章,并使其变得毫无意义?
如果你只对最后一个问题回答 'yes',你可能不需要这里的 ViewModel:) 您需要其他架构吗?不,你不需要架构。您需要显示一个通知,那就去做吧!
如果你是真正的MVVM粉丝,你还是可以通过的。
首先,删除 ViewModelProviders.of
因为它不可能在这里使用。它需要 activity 或片段,而你两者都没有。 ViewModelProvider 的目的是在重新创建 activity/fragment 时为您提供相同的视图模型实例 - 这显然不是您的情况。
其次,自己构建viewmodel:new NotificationViewModel()
.
第三,return 来自您的视图模型的普通对象而不是实时数据,因为您的数据不是实时的。
public class NotificationViewModel {
MessageNotification getNextNotification() {
// ...
}
}
请注意,您甚至不需要扩展 ViewModel
class,因为您不使用 ViewModelProviders。
如果问题是读取 SQLite 数据库,则不需要 ViewModel。问题可能是无法直接调用挂起函数 (viewmodelscope.launch{}),但有一个简单的解决方法:runBlocking。
我假设 Broadcastreceiver 已经在后台,所以不需要启动后台协程。
runBlocking {
val reminders = favoriteDao.queryAllReminders()
reminders.forEach { reminder ->
Log.i("Reminder", reminder.info)
}
}