我有一个使用共享首选项实现的应用小部件。
现在我正在将其迁移到Data Store。
这里的问题是如何在 AppWidgetProvider(BroadCastReceiver 的子类)中观察/收集流数据?
重现问题的最低代码。
MyAppWidgetProvider:
class MyAppWidgetProvider : AppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId)
}
}
}
internal fun updateAppWidget(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int
) {
RemoteViews(context.packageName, R.layout.widget_layout).also { views ->
val data = loadDataFromPreferences(context, appWidgetId)
views.setTextViewText(
R.id.textview_title,
data.title
)
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
数据存储工具:
internal fun loadDataFromPreferences(context: Context, appWidgetId: Int): Flow<Data> {
val dataStore: DataStore<Preferences> = context.createDataStore(
name = PREFS_NAME,
migrations = listOf(SharedPreferencesMigration(context, PREFS_NAME))
)
val PREF_TITLE = stringPreferencesKey(PREF_PREFIX_KEY + appWidgetId + PREF_SUFFIX_TITLE)
return dataStore.data
.catch {
if (it is IOException) {
it.printStackTrace()
emit(emptyPreferences())
} else {
throw it
}
}
.map { preferences ->
// No type safety.
val title = preferences[PREF_TITLE] ?: ""
Data(title)
}
}
笔记:
- 数据 - 自定义模型类
- loadDataFromPreferences() 返回类型是
Data
使用共享首选项时。将其更改Flow<Data>
为 DataStore,这会导致updateAppWidget()
行中的错误:
val data = loadDataFromPreferences(context, appWidgetId)
- 因为数据类型已更改为 Flow。