Ami*_*war 6 android kotlin appwidgetprovider android-room kotlin-coroutines
我有一个应用程序从 api 获取数据并缓存在数据库中。我希望能够在小部件中显示这些数据(来自数据库),并添加一个按钮来更新数据,按下该按钮将获取数据并更新数据库,从而更新小部件。问题是因为我使用的是 mvvm,所以我不确定是否可以利用 livedata 和 jetpack 组件的花哨支持。
所以我只是在 widget update fun 中创建了一个 Dao 引用并获取了数据库。这确实获取了数据,但它没有更新文本视图,我记录了它并且它正确地向我显示了数据。
companion object {
internal fun updateAppWidget(
context: Context, appWidgetManager: AppWidgetManager,
appWidgetId: Int
) {
val db = AppDatabase.getInstance(context.applicationContext).weatherDao()
val views = RemoteViews(context.packageName, R.layout.weather_widget)
GlobalScope.launch {
val weather = db.getCurrentWeatherMetricAsync()
Log.d("TAG_TAG_TAG", "weather: " + weather.temperature);
withContext(Dispatchers.Main) {
views.setTextViewText(R.id.tv_counter, " asd " + weather.temperature)
}
}
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
Run Code Online (Sandbox Code Playgroud)
道对此有暂停的乐趣。
@Query("select * from current_weather where id = 0")
suspend fun getCurrentWeatherMetricAsync(): CurrentMetric
Run Code Online (Sandbox Code Playgroud)
您能告诉我如何与数据库交互以及与应用程序存储库交互的正确方法吗?
由于您正在使用 Room 的挂起功能,因此您可以将其CoroutineScope与Dispatchers.Main(https://medium.com/androiddevelopers/room-coroutines-422b786dc4c5、https://medium.com/androiddevelopers/coroutines-on-android-part -i-getting-the-background-3e0e54d20bb)。
CoroutineScope(Dispatchers.Main.immediate).launch {
val weather = AppDatabase.getInstance(context.applicationContext).weatherDao().getCurrentWeatherMetricAsync()
val views = RemoteViews(context.packageName, R.layout.weather_widget)
views.setTextViewText(R.id.tv_counter, " asd " + weather.temperature)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
Run Code Online (Sandbox Code Playgroud)
如果您不使用挂起函数甚至 Room,您可以使用Dispatchers.IO异步加载数据并在同一线程中更新 RemoteViews,而无需withContext(Dispatchers.Main)因为 RemoteViews 不是“我们的”,我们只是告诉启动器他应该在该视图上设置此数据。默认情况下,这是在另一个无 UI 线程中完成的 - 甚至在应用程序创建/拥有的线程中也没有。
这是我找到的唯一方法,因为既然如此AppWidgetProvider,BroadcastReceiver你就不能在其中使用架构组件(/sf/answers/3310458231/)。只要您更新数据库(在JobIntentService,Worker(WorkManager),,Coroutines无论什么时候)并获取最新记录updateAppWidget()(就像您现在所做的那样),就强制更新小部件。
这是强制小部件更新的方便扩展函数:
fun Context.updateWidget() {
val widgetUpdateIntent = Intent(this, Widget::class.java).apply {
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
putExtra(
AppWidgetManager.EXTRA_APPWIDGET_IDS,
AppWidgetManager.getInstance(this@updateWidget).getAppWidgetIds(
ComponentName(
this@updateWidget,
Widget::class.java
)
)
)
}
sendBroadcast(widgetUpdateIntent)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2357 次 |
| 最近记录: |