I make a call http request and update widget but i...
# glance
m
I make a call http request and update widget but i get error after i did update widget .UI updated but then give an error.I share to my error for your better understanding.
p
can you post some code? Without that it is impossible to guess what is going on 🙂
m
I have published to github.If you can help me i really happy https://github.com/mehmetpeker/Jetpack-Glance-Reddit-Widget
y
Just a guess, but I think this update is only temporary until the actual widget refreshes
Copy code
private suspend fun updateGlanceWidget(list: List<RedditItemModel>) {
        val glanceId =
            GlanceAppWidgetManager(appContext).getGlanceIds(RedditWidget::class.java)
                .firstOrNull()
        glanceId?.let { id ->
            RedditWidget(list).update(appContext,id)
        }
    }
But I haven't used the state updates myself.
m
Copy code
public suspend fun updateAppWidgetState(
    context: Context,
    glanceId: GlanceId,
    updateState: suspend (MutablePreferences) -> Unit,
) {
    updateAppWidgetState(context, PreferencesGlanceStateDefinition, glanceId) {
        it.toMutablePreferences().apply {
            updateState(this)
        }
    }
}
this function uses preferences but i want to send model list to widget
y
The broadcast receiver is probably alive for a very short amount of time. So if you are not using the state or saving it yourself, I would worry that it would get overwritten shortly after it updates. How do you keep this data if the system decides to redraw your widget?
m
I can't, so I asked for help.
y
Did you read the article, was it helpful?
m
I want to pass list with custom model to widget but this article doesn't mention about that.
y
I don't think it's possible, I think the state is stored like a map.
m
@Piotr Prus Do you have any idea about that?I would be very happy if you could help me
y
Another article by @Marcel Pinto https://medium.com/androiddevelopers/demystifying-jetpack-glance-for-app-widgets-8fbc7041955c
Copy code
// … somewhere outside of the composition (e.g ActionCallback).
updateAppWidgetState(context, glanceId) { state ->
  state[CounterKey] = (state[CounterKey] ?: 0) + 1
}

// Don't forget to trigger the update. :)
MyAppWidget().update(context, glanceId)
m
@yschimke Thank you very much for all your help but this method is not suitable for my purpose.I have a custom model list what have a ten item and i want to pass to widget.How can i save all item to preferences? I think i cant
m
you can use a GlanceStateDefinition that uses protobuf or Serialization data store to store complex objects. Otherwise use your own caching mechanism and update the widget once data changes there.
y
"own caching mechanism" = something like Jetpack Datastore?
@yschimke Thank you
@Marcel Pinto I hope Google produces more content on this.Thank you too
y
I wouldn't have recommended those patterns as they were early explorations with the Glance API, that hopefully fed into the designs for support for updates and background loading. If it works it works, but I think there are better cleaner options now.
m
Do you know what are the better cleaner options?I didn't found any example using custom state definition or serialization for that.
y
I think it's following @Marcel Pinto’s article and advice.
I don't think initiateLoad called by the BroadcastReceiver is a pattern everyone should have to write. https://github.com/joreilly/PeopleInSpace/blob/c666ae73b55f06bdd30293262b0cefea72e[…]ava/com/surrus/peopleinspace/glance/util/BaseGlanceAppWidget.kt
m
I read Marcel's article, but am I missing something?
m
There are two things. One is how to persist your state so you don't have to fetch it again and it's available via 'currentState' inside your composable. This is done with GlanceStateDefinition. For complex state you should use data store with serialization or protobuf. The second thing is how to fetch data or initial state. There is no in-built mechanism for that right now. My advice is to use WorkManager onUpdate with the proper policy and checks (to avoid launching it multiple times). The worker can fetch the state/data and persist it so when you call widget update the stat is available
"own caching mechanism" = something like Jetpack Datastore? No. I mean your own DB or in-memory cache. You can access/pass dependencies/classes in your widget, without using the GlanceStateDefinition. The problem is that the process might die between updates, so you should make sure the cache is loaded again before updating the widget