API 32以下版本GlanceAppWidget组件刷新失效问题求助
Compose Glance桌面组件API<32版本状态更新不刷新问题
我用Compose Glance开发了一款桌面组件,该组件在API 32版本上运行完全正常,但在所有API<32的版本中,当偏好设置/状态更新时,组件无法刷新。我已尝试深入理解偏好状态与GlanceWidget的数据交互逻辑,但仍未解决问题,查阅Google官方教程、开发者文章及相关教程后也没找到办法。
原始GlanceAppWidget实现代码
class CrTWidget : GlanceAppWidget() { override val stateDefinition: GlanceStateDefinition<*> = PreferencesGlanceStateDefinition //override val stateDefinition = TickerInfoStateDefinition override suspend fun provideGlance(context: Context, id: GlanceId) { //Log.v("GlanceAppWidget", "provideGlance") provideContent { //we're in composable context val prefs = currentState<Preferences>() var prefsMap = prefs.asMap() //val prefs = currentState<TickerInfo>() // create your AppWidget here Log.v("GlanceAppWidget", "provideContent") MyContent(prefsMap) } } @Composable private fun MyContent(mapTickerz : Map<Preferences.Key<*>, Any>) { //https://developer.android.com/jetpack/compose/glance/glance-app-widget val listTickerz = mutableListOf<String>() mapTickerz.forEach{ listTickerz.add(it.key.toString()) //Log.v("GlanceAppWidget", "KEY FOUND IS IN PREFS MAP IS ${it.key}") } Log.v("GlanceAppWidget","PREFS MAP IS $listTickerz") } SomeCompositionWithmapTickerz(mapTickerz) }
原始GlanceAppWidgetReceiver实现代码
class CrTWidgetReceiver : GlanceAppWidgetReceiver() { override val glanceAppWidget: GlanceAppWidget = CrTWidget() override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) { super.onUpdate(context, appWidgetManager, appWidgetIds) Log.v("CrTWidgetReceiver", "onUpdate GlanceAppWidgetReceiver") observeData(context) } override fun onReceive(context: Context, intent: Intent) { super.onReceive(context, intent) Log.v("CrTWidgetReceiver", "onReceive GlanceAppWidgetReceiver + ${intent.action}") if(intent.action == context.packageName + ".UpdateWIDGET"){ observeData(context) } /*if(intent.action == "android.appwidget.action.APPWIDGET_UPDATE"){ observeData(context) }*/ } private fun observeData(context: Context) { try{ Log.v("CrTWidgetReceiver", "observeData STARTED") val applicationScope = CoroutineScope(SupervisorJob()) // Using by lazy so the database and the repository are only created when they're needed // rather than when the application starts val database by lazy { DatabasePT.getDatabase(context, applicationScope) } val repository by lazy { RepositoryPT(database.CrTickerDAO(), database.CrPairsDAO()) } var mapTickers: MutableMap<String, CrTickerModel> = mutableMapOf() //fetch data from repo var firstFlowReached = false CoroutineScope(SupervisorJob()).launch { repository.getAllDataSymbol.takeWhile { !firstFlowReached }.collect {syms -> //Log.v("CrTWidgetReceiver", "collect OCCURENCE") syms.forEach {symbol -> mapTickers[symbol.cryptoTickName] = symbol } GlanceAppWidgetManager(context).getGlanceIds(CrTWidget::class.java).forEach { glanceId -> updateAppWidgetState(context, glanceId) { pref -> pref.clear() mapTickers.forEach { symbol -> Log.v("CrTWidgetReceiver", "LAST PRICE OF ${symbol.value.cryptoTickSymbol} IS ${symbol.value.cryptoTickQuote}") val tick = symbol.value.cryptoTickSymbol val tickQuoter = symbol.value.cryptoTickQuoter val price = symbol.value.cryptoTickQuote val source = symbol.value.cryptoTickSource pref[stringPreferencesKey(symbol.value.cryptoTickName)] = "$tick¤$tickQuoter¤$price¤$source" } } CrTWidget().update(context, glanceId) } firstFlowReached = true Log.v("CrTWidgetReceiver", "EXITING COLLECT") } } }catch (e : Exception){ var stringWriter = StringWriter() e.printStackTrace(PrintWriter(stringWriter)) Log.e("CrTWidgetReceiver", "observeData ERROR $stringWriter") } } }
编辑补充:尝试直接收集Flow的实现
尝试相关建议后,改为在provideGlance中直接收集Flow的方式实现,无需调用CrTWidget().updateAll(context)即可自动更新状态,但问题依旧:API>32版本正常,其他版本首次更新后便停止刷新。
代码如下:
class CrTWidget : GlanceAppWidget() { override suspend fun provideGlance(context: Context, id: GlanceId) { val applicationScope = CoroutineScope(SupervisorJob()) // Using by lazy so the database and the repository are only created when they're needed // rather than when the application starts val database by lazy { DatabasePT.getDatabase(context, applicationScope) } val repository by lazy { RepositoryPT(database.CrTickerDAO(), database.CrPairsDAO()) } provideContent { var watchTickerState = repository.getAllDataSymbol.collectAsState(initial = listOf( CrTickerModel(cryptoTickTimestamp = "0", cryptoTickName = "EMPTY", cryptoTickNameAPI = "EMPTY", cryptoTickQuote = "EMPTY", cryptoTickQuoter = "EMPTY", cryptoTickSource = "BINANCE", cryptoTickSymbol = "EMPTY") )) //we're in composable context val prefs = currentState<Preferences>() var prefsMap = prefs.asMap() MyContent(watchTickerState) } } @Composable private fun MyContent(watchTickerState: State<List<CrTickerModel>>) { //https://developer.android.com/jetpack/compose/glance/glance-app-widget watchTickerState.value.let { modelList -> Log.v("recomposed", modelList.toString()) SomeCompositionWithList(modelList) } } }
寻求解决思路。
内容的提问来源于stack exchange,提问作者PsyTrxOps
相关产品推荐
相关产品推荐

