Re: [android-beginners] Re: Problem with AppWidget Using a Service

2010-06-23 Thread Kostya Vasilyev

Jake,

onUpdate is passed an explicit list of just the widget ids that need to 
be updated. Supposedly, there could be widgets that belong to this 
provider but don't need updating (e.g. on a scrolled-off home screen 
portion).


Pushing a RemoveViews object to a paricular widget is done by calling:

manager.updateAppWidget(int widgetId, updateViews);


It's also possible to update all widgets that belong to a particular 
widget provider, and this is the approach service-based widgets take, 
supposedly to avoid paying service start-up costs for each widget id.


In this case, a single RemoteViews is pushed to all widgets with a 
single call to:


manager.updateAppWidget(ComponentName thisWidget, updateViews);


-- Kostya

23.06.2010 18:57, Jake Colman пишет:

Kostya,

Thanks.  That worked like a charm.

I noticed in sample AppWidget code that does not use a service, that it
iterates the appWidgetIds array so that it updates all instances of the
widget.  However, in sample code that uses a Service, that iteration is
not done.  Is that because it is not needed for some reason?  How would
one update multiple instances using a service-based solution?

Thanks.

...Jake

   

KV == Kostya Vasilyevkmans...@gmail.com  writes:
 

KV  Jake,

KV  The error is in the way your code instantiates ComponentName.

KV  Instead of:

KV  ComponentName thisWidget = new ComponentName(this, 
ZMUpdateService.class);

KV  Do this:

KV  ComponentName thisWidget = new
KV  ComponentName(this,*ZmanMinderAppWidget*.class);

KV  The error message was trying to convey same thing...

KV  -- Kostya

KV  23.06.2010 17:39, Jake Colman ?:
  I am trying to create a simple AppWidget using a service to initialize
  the content in the onUpdate() method.  The data is not being refreshed
  and logcat shows me the following warning:

  AppWidgetService  W  updateAppWidgetProvider: provider doesn't exist:
  ComponentInfo{com.jnc.zmanminder/com.jnc.zmanminder.ZMUpdateService}

  I must be missing something obvious but I cannot figure it out.

  My AppWidget class (edited for brevity) looks as follows:

  public class ZmanMinderAppWidget extends AppWidgetProvider {
  public void onUpdate(Context context,
  AppWidgetManager appWidgetManager, int[] appWidgetIds) {
  context.startService(new Intent(context, ZMUpdateService.class));
  }
  }

  My Service class (edited for brevity) looks as follows:

  public class ZMUpdateService extends Service {
  public void onStart(Intent intent, int startId) {
  RemoteViews updateViews = buildUpdate(this);
  ComponentName thisWidget = new ComponentName(this,
  ZMUpdateService.class);
  AppWidgetManager manager = AppWidgetManager.getInstance(this);
  manager.updateAppWidget(thisWidget, updateViews);
  }

  public IBinder onBind(Intent arg0) {
  return null;
  }

  public RemoteViews buildUpdate(Context context) { 
  Time time = new Time();
  time.setToNow();  
  RemoteViews views = new
  RemoteViews(context.getPackageName(),R.layout.widget);
  views.setTextViewText(R.id.time, time.format(%I:%M%p));
  return views;
  }
  }

  The ZMUpdateService service is defined in my manifest file.

  Thanks for any help.

  ...Jake




KV  -- 
KV  Kostya Vasilev -- WiFi Manager + pretty widget --

KV  http://kmansoft.wordpress.com

KV  -- 
KV  You received this message because you are subscribed to the Google

KV  Groups Android Beginners group.

KV  NEW! Try asking and tagging your question on Stack Overflow at
KV  http://stackoverflow.com/questions/tagged/android

KV  To unsubscribe from this group, send email to
KV  android-beginners+unsubscr...@googlegroups.com
KV  For more options, visit this group at
KV  http://groups.google.com/group/android-beginners?hl=en

   



--
Kostya Vasilev -- WiFi Manager + pretty widget -- http://kmansoft.wordpress.com

--
You received this message because you are subscribed to the Google
Groups Android Beginners group.

NEW! Try asking and tagging your question on Stack Overflow at
http://stackoverflow.com/questions/tagged/android

To unsubscribe from this group, send email to
android-beginners+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-beginners?hl=en


Re: [android-beginners] Re: Problem with AppWidget Using a Service

2010-06-23 Thread Kostya Vasilyev

Jake,

Using a service for a widget that's not doing anything lengthy to 
prepare updates seems like a bit of an overkill. Certainly it works, but 
probably not necessary.


On the other hand, using a service is definitely the way to go for 
widgets that fetch data from the Internet or some other way that can 
take a long time.


Another issue is - this is all good, until someone uses a task killer, 
discovers the service, complains that the widget spanws an unnecessary 
service that uses too much memory and cpu time, kills it, and 
uninstalls. Has happened to me.


Good thing Android 2.x includes great tools to show how memory and 
battery are used.


I hope users learn to use these tools and exercise good judgement before 
killing a service just because it's there.


-- Kostya

23.06.2010 20:15, Jake Colman пишет:

Kostya,

That makes perfect sense.  It seems like a service-based update is
really the right way to go.  It avoids any potential timeout issue and
is allows updating of all widgets at once.

Thanks for your help.

...Jake


   

KV == Kostya Vasilyevkmans...@gmail.com  writes:
 

KV  Jake,

KV  onUpdate is passed an explicit list of just the widget ids that
KV  need to be updated. Supposedly, there could be widgets that
KV  belong to this provider but don't need updating (e.g. on a
KV  scrolled-off home screen portion).

KV  Pushing a RemoveViews object to a paricular widget is done by
KV  calling:

KV  manager.updateAppWidget(int widgetId, updateViews);

KV  It's also possible to update all widgets that belong to a
KV  particular widget provider, and this is the approach
KV  service-based widgets take, supposedly to avoid paying service
KV  start-up costs for each widget id.

KV  In this case, a single RemoteViews is pushed to all widgets with
KV  a single call to:

KV  manager.updateAppWidget(ComponentName thisWidget, updateViews);

KV  -- Kostya

KV  23.06.2010 18:57, Jake Colman пишет:
  Kostya,

  Thanks.  That worked like a charm.

  I noticed in sample AppWidget code that does not use a service, that it
  iterates the appWidgetIds array so that it updates all instances of the
  widget.  However, in sample code that uses a Service, that iteration is
  not done.  Is that because it is not needed for some reason?  How would
  one update multiple instances using a service-based solution?

  Thanks.

  ...Jake


  KV == Kostya Vasilyevkmans...@gmail.com   writes:

KV  Jake,

KV  The error is in the way your code instantiates ComponentName.

KV  Instead of:

KV  ComponentName thisWidget = new ComponentName(this,
KV  ZMUpdateService.class);

KV  Do this:

KV  ComponentName thisWidget = new
KV  ComponentName(this,*ZmanMinderAppWidget*.class);

KV  The error message was trying to convey same thing...

KV  -- Kostya

KV  23.06.2010 17:39, Jake Colman ?:
 I am trying to create a simple AppWidget using a service to
 initialize
 the content in the onUpdate() method.  The data is not being
 refreshed
 and logcat shows me the following warning:
  
 AppWidgetService W updateAppWidgetProvider: provider doesn't exist:
 
ComponentInfo{com.jnc.zmanminder/com.jnc.zmanminder.ZMUpdateService}
  
 I must be missing something obvious but I cannot figure it out.
  
 My AppWidget class (edited for brevity) looks as follows:
  
 public class ZmanMinderAppWidget extends AppWidgetProvider {
 public void onUpdate(Context context,
 AppWidgetManager appWidgetManager, int[] appWidgetIds) {
 context.startService(new Intent(context, ZMUpdateService.class));
 }
 }
  
 My Service class (edited for brevity) looks as follows:
  
 public class ZMUpdateService extends Service {
 public void onStart(Intent intent, int startId) {
 RemoteViews updateViews = buildUpdate(this);
 ComponentName thisWidget = new ComponentName(this,
 ZMUpdateService.class);
 AppWidgetManager manager = AppWidgetManager.getInstance(this);
 manager.updateAppWidget(thisWidget, updateViews);
 }
  
 public IBinder onBind(Intent arg0) {
 return null;
 }
  
 public RemoteViews buildUpdate(Context context) {  
 Time time = new Time();
 time.setToNow();   
 RemoteViews views = new
 RemoteViews(context.getPackageName(),R.layout.widget);
 views.setTextViewText(R.id.time, time.format(%I:%M%p));
 return views;
 }
 }
  
 The ZMUpdateService service is defined in my manifest file.
  
 Thanks for any help.
  
 ...Jake
  
  
  

KV  -- 
KV  Kostya Vasilev -- WiFi 

Re: [android-beginners] Re: Problem with AppWidget Using a Service

2010-06-23 Thread Mark Murphy
On Wed, Jun 23, 2010 at 12:36 PM, Kostya Vasilyev kmans...@gmail.com wrote:
 On the other hand, using a service is definitely the way to go for widgets
 that fetch data from the Internet or some other way that can take a long
 time.

There are (at least) three costs to doing work in the app widget
itself versus an IntentService:

1. The app widget provider might get killed if it takes too long (~10 seconds).

2. Tying up the main application thread, even for fairly short bursts,
will cause your app's activity, if visible to freeze up. Even really
short bursts (e.g., 250ms) can cause your UI to appear janky if the
user is actively using it.

3. Your code is running at foreground priority, and so it will steal
CPU cycles from anything truly in the foreground, such as a real-time
game.

Since app widget providers themselves cannot maintain state, they
inevitably have to use flash storage, even if just for reads. Doing a
simple database query is perhaps fast enough that you could get away
with doing it in the app widget provider itself. However, if you write
to flash, you want to move that to the IntentService, because flash
writes can get crazy slow (see the Zippy Android Apps presentation
from Google I|O 2010). And, of course, network I/O may take
indefinitely long.

Hence, unless the app widget functionality is trivially small, you're
probably going to want an IntentService, task killers be damned.

-- 
Mark Murphy (a Commons Guy)
http://commonsware.com | http://github.com/commonsguy
http://commonsware.com/blog | http://twitter.com/commonsguy

_The Busy Coder's Guide to *Advanced* Android Development_
Version 1.6 Available!

-- 
You received this message because you are subscribed to the Google
Groups Android Beginners group.

NEW! Try asking and tagging your question on Stack Overflow at
http://stackoverflow.com/questions/tagged/android

To unsubscribe from this group, send email to
android-beginners+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/android-beginners?hl=en