1

This is good documentation about the lifecycle of an Android Activity, but I can't find any for a Widget lifecycle. Documentation talks about AppWidgetProvider broadcast message for onUpdate, onEnabled, onDeleted, onAppWidgetOptionsChanged, etc.

The widget persists between reboots and across AppWidgetHost application restarts and AppWidgetProvider restarts, so understanding the lifecycle is important.

So, here's the lifecycle as far as I can tell:

  • Launcher(AppWidgetHost) wishes to add widget

  • Launcher asks AppWidgetManager for list of AppWidgetProviders

  • AppWidgetManager creates widget instance, assigns widgetId an stores in its secret DB

  • User selected widget and places it on Launcher 'home page'

  • Launcher stores home page location of widget, and persistent widgetId in DB

  • AppWidgetManager call AppWidgetProvider 'configuration activity' (if there is one)

    • Configuration activity creates RemoteViews() and calls widgMgr.updateAppWidget(widgId, views)
  • ?? Does AppWidgetProvider need to persistently store widgetId and associated config info?

  • On reboot, or restart of launcher, or restart/reinstall of AppWidgetProvider, AppWidgetManager call .onUpdate for each widgetId -- perhaps to recreate the RemoteView associated with the widget?

  • ... at some one user may delete widget

    • Launcher(AppWidgetHost) deletes persistent info about widgetId
    • AppWidgetManager sends APPWIDGET_DELETE broadcast, AppWidgetProvider .onDeleted called
    • AppWidgetProvider deletes persistent info about that widgetId?

The fact that Launcher(AppWidgetHost) and AppWidgetManager, and presumably AppWidgetProvider must maintain persistent info associated with a widgetId, makes it important to know the lifecycle of a widget from creation to enable, disable, resume, to reboot, to various packages being reinstalled, to deletion.

In this other widget lifecycle question no lifecycle is found. @CommmonsWare (I think) notes that the AppWidgetProvider's various objects are not stable even between broadcast msgs, like onUpdate, etc. (I think that the AppWidgetProvider may be just a BroadcastReceiver and not necessarily a Activity or Application where static variables or instance variables would be somewhat persistent.

AppWidgetManager persistent Database of widgets

For those searching for info:

The AppWidgetManager seems to persist its information about existing widget instances, providers and hosts in:

/data/system/users/0 # cat appwidgets.xml

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<gs>
<p pkg="revive.rwidg" cl="revive.rwidg.RWidg" />
<h pkg="com.teslacoilsw.launcher" id="400" />
<g id="1" h="0" min_width="0" min_height="0" max_width="0"  max_height="0" host_category="0" />
<g id="2" h="0" min_width="0" min_height="0" max_width="0"     max_height="0" host_category="0" />
<g id="3" h="0" min_width="0" min_height="0" max_width="0"     max_height="0" host_category="0" />
<g id="2b" h="0" p="0" min_width="5a" min_height="42" max_width="85"     max_height="65" host_category="1" />
<g id="2e" h="0" p="0" min_width="5a" min_height="42" max_width="85"     max_height="65" host_category="1" />
<b packageName="com.teslacoilsw.launcher" />
</gs> 

Current information about the widget, hosts and providers is available through the (linux, adb, shell) command:

dumpsys appwidget

User: 0
  Providers:
    [0] provider com.android.contacts/.socialwidget.SocialWidgetProvider:
      min=(66561x10241)   minResize=(66561x10241) updatePeriodMillis=86400000 resizeMode=01 autoAdvanceViewId=-1 initialLayout=#7f04008a uid=10000 zombie=false
    [1] provider com.android.email/.provider.WidgetProvider:
      min=(46081x28161)   minResize=(46081x28161) updatePeriodMillis=0 resizeMode=33 autoAdvanceViewId=-1 initialLayout=#7f040045 uid=10009 zombie=false
    [2] provider com.android.settings/.widget.SettingsAppWidgetProvider:
      min=(66561x10241)   minResize=(66561x10241) updatePeriodMillis=0 resizeMode=01 autoAdvanceViewId=-1 initialLayout=#7f040085 uid=1000 zombie=false
    [3] provider revive.rwidg/.RWidg:
      min=(12801x12801)   minResize=(12801x12801) updatePeriodMillis=30000 resizeMode=01 autoAdvanceViewId=-1 initialLayout=#7f090023 uid=10040 zombie=false

  AppWidgetIds:
    [0] id=1
      hostId=1024 com.teslacoilsw.launcher/10033
      host.callbacks=com.android.internal.appwidget.IAppWidgetHost$Stub$Proxy@41d4d2c8
    [1] id=2
      hostId=1024 com.teslacoilsw.launcher/10033
      host.callbacks=com.android.internal.appwidget.IAppWidgetHost$Stub$Proxy@41d4d2c8
    [2] id=3
      hostId=1024 com.teslacoilsw.launcher/10033
      host.callbacks=com.android.internal.appwidget.IAppWidgetHost$Stub$Proxy@41d4d2c8
    [3] id=43
      hostId=1024 com.teslacoilsw.launcher/10033
      provider=revive.rwidg/.RWidg
      host.callbacks=com.android.internal.appwidget.IAppWidgetHost$Stub$Proxy@41d4d2c8
    [4] id=46
      hostId=1024 com.teslacoilsw.launcher/10033
      provider=revive.rwidg/.RWidg
      host.callbacks=com.android.internal.appwidget.IAppWidgetHost$Stub$Proxy@41d4d2c8

  Hosts:
    [0] hostId=1024 com.teslacoilsw.launcher/10033:
      callbacks=com.android.internal.appwidget.IAppWidgetHost$Stub$Proxy@41d4d2c8
      instances.size=5 zombie=false

  Deleted Providers:

  Deleted Hosts:

AppWidgetProvider Broadcast Receiver

(As @CommonsWare notes...) The AppWidgetProvider extends BroadcastReceiver, so the main interface your widget class has is being sent broadcast intents through its onReceive(Context, Intent) method. Your widget package may not be an Android Application or contain an Android Activity, thus the persistence and lifecycle of Applications and Activitys don't apply.

Thus you can't store information in static variables or instance variables of your widget class because they may not continue to exist for the duration of your widget instances.

Ribo
  • 3,363
  • 1
  • 29
  • 35
  • 1
    "Does AppWidgetProvider need to persistently store widgetId and associated config info?" -- pretty much, yes. "perhaps to recreate the RemoteView associated with the widget?" -- yes, at least for the reboot scenario, as a `RemoteView` is not persistable. IIRC they trigger `onUpdate()` for an app update for the provider, because it may be that the `PendingIntent` objects you had before are no longer good (e.g., you refactored and now an activity is somewhere different than before). – CommonsWare Jun 15 '21 at 16:50
  • 1
    "I think that the AppWidgetProvider may be just a BroadcastReceiver" -- yes. "a Activity or Application where static variables or instance variables would be somewhat persistent" -- your app's process can be terminated at any point when your UI is in the background. Treat static variables as a cache, nothing more. – CommonsWare Jun 15 '21 at 16:50
  • @CommonsWare, edited the question to add info about AppWdgetManager persistence. – Ribo Jun 15 '21 at 18:50

0 Answers0