5

In my onUpdate method in my AppWidgetProvider class, I ended up executing a non-trivial amount of code so that I can completely recreate a new RemoteView object. The reality is I really only need to be setting the text in one of the TextViews in the RemoteViews each time I update.

Is there any way to just modify the RemoteViews that a particular widget is already using?

Adinia
  • 3,722
  • 5
  • 40
  • 58
Kurtis Nusbaum
  • 30,445
  • 13
  • 78
  • 102

3 Answers3

20

First, RemoteView is not a View. It's a set of instructions that build a View hierarchy. It is used to recreate a View in another process (App Widgets do not execute in your app's process). As such it's serializable and mutable.

So, when you initialize a RemoteView just store a reference to it somewhere, e.g. in a field of your custom AppWidgetProvider. Next time you need it, get it from field and the change something on it. For changing the string in a TextView use setString(..).

remoteView.setString(textViewId, "setText", "some text for TextView")
Peter Knego
  • 79,991
  • 11
  • 123
  • 154
  • So I'm creating this remoteView in a broadcast reciever which is of course transient. Would saving a reference in a static variable to a solution to that hurdle? – Kurtis Nusbaum Oct 11 '11 at 22:55
  • 1
    Yes it would be ok. RemoteViews are totally detached from app/activity context and would not leak memory. – Peter Knego Oct 12 '11 at 05:53
  • I thought this broadcast receiver is short lived (for only duration of onReceive, then a new instance pops up), would the reference be destroyed at some point? – SIr Codealot Mar 29 '13 at 21:30
  • 2
    I'm tempted to do this, but a static var assumes you only have one widget, doesn't it? If there are multiple widgets, each of which has its own RemoteViews instance, this wouldn't work. I'm tempted to save the RemoteViews as a parcelable to the AppWidgetOptions, which is set per-widget ID. – thom_nic May 17 '13 at 13:26
  • @Mike definitely yes, when the instance is gone, so is the reference to the RemoteViews suggested in this answer... – Jose_GD Jan 15 '14 at 20:16
  • @Jose_GD a static var is never gone, unless explicitly nulled. – Amir Uval Mar 21 '15 at 23:54
  • @thom_nic you can probably use a static HashMap from appWidgetId to RemoteViews. – Amir Uval Mar 21 '15 at 23:55
  • @PeterKnego yes it would leak memory, specially if you are setting images into the remote view, as the instructions are not erased on each run; you will end up running all the accumulated instructions every time the widget is run – htafoya Sep 13 '15 at 20:31
17

This is the 2013 update if you are using current API's. In your WidgetProvider class' method that will perform an update:

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
rv = new RemoteViews(context.getPackageName(), R.layout.widgetlayout); 
rv.setTextViewText(R.id.ofTextViewInWidgetLayoutXML, "Hello World");
appWidgetManager.partiallyUpdateAppWidget(appWidgetIds[i], rv);

Note that it is no longer remoteView.setString but remoteView.setTextViewText

Mark Lapasa
  • 1,644
  • 4
  • 19
  • 37
0

You can update the remote views and then call

ComponentName componentName= new ComponentName(context, YourClass.class);
AppWidgetManager.getInstance(context).updateAppWidget(componentName, remoteViews);

on, which AFAIK should update the widget

martinpelant
  • 2,961
  • 1
  • 30
  • 39