App Widget update: failed binder transaction, RemoteViews, setImageURI and orientation changes

I have a problem updating AppWidgets and merging constraints / errors in android is preventing me from finding a workaround.

My app widget is themed, so I need to be able to update the images on it at runtime (as well as text views and intents). There are up to 9 images that I update, but the size of the graphics used is quite modest (max 11kb pngs). The total size of the data I'm pushing through the RemoteViews object should be less than 100KB, which is also within 1MB. I think the actual available resources on the screen end up being larger than the original pngs, but 10% of the limit seems reasonable enough to account for that. However, with some phones and launchers, I get "FAILED BINDER TRANSACTION" errors.

There are two solutions I have found for this:

1) Use setImageViewUri (which calls setImageURI) instead of setImageViewResource with RemoteViews object, this gets rid of sending drawings via RemoteViews object and loads the image from URI. Resolves memory error (see https://groups.google.com/forum/#!topic/android-developers/KKEyW6XdDvg/discussion )

2) Split updates to app widget into multiple calls to RemoteView. So I update 3 images, call updateAppWidget, create a new RemoteViews object, update the next 3 images, call updateAppWidget, etc.

The problem with the first approach is that it only works for medium density devices. All other devices display images incorrectly due to a bug in the Android codebase (see bug report: http://code.google.com/p/android/issues/detail?id=22590 )

The problem with the second approach is that when the screen orientation changes, android destroys and recreates the widgets using the last call to RemoteViews, which it keeps in some secret location. This results in the application not being completely redrawn because I split calls to the RemoteView and the widget becomes unusable. There seems to be no reliable way to figure out when android destroys and recreates appwidgets - onConfigurationChanged on the service doesn't always fire and no activity level call is made (like onUpdate, onReceive) that I can find. In order for the widgets to be completely and correctly redrawn when the orientation changes, I can only use one call to RemoteViews (updateAppWidget) to prevent this solution from working.

Does anyone know how to get around this? I am wondering if it is possible to implement my own RemoteViews that called the notImageURI function without bugs (in a custom ImageView class) so that the scaling happens correctly. It seems like most of the work is just updating a few widgets and I'm not sure if android will let me extend RemoteViews / ImageView this way.

Do I need to intercept the android at all when changing the screen orientation and force it to redraw the entire widget?

Would love to hear any other suggestions or workarounds! Thank.

+3


source to share


1 answer


I faced the same problems while developing AppWidgets collections. It happened many times:

  • When rotating the ListView disappeared completely,
  • Button listeners (actually called PendingIntents

    ) stopped responding;
  • Changes to images through were setImageViewResource

    not updated;

.. etc. I came to the same conclusion as you: android destroys and recreates the widgets using the last call to RemoteViews, which it stores in some secret location . In recognition of this, it was about the exact assignment of the calls AppWidgetManager.getInstance(context).updateAppWidget()

, because I wanted to disable clickListeners (or PendingIntents) after telling the ListView to update (it was a network operation to call web services and receive a non-trivial amount of data) and wanted to enable listeners after the download was complete ListView while saving fully loaded RemoteViews to handle rotation.

I was close to giving up and using it as an alternative.



Do I need to intercept the android at all when changing the screen orientation and force it to redraw the entire widget?

.. a service in which to catch changes in Android, unlike AppWidget. If you are running out of options, I would suggest you try:

public class MyWidget extends AppWidgetProvider {
@Override
    public void onConfigurationChanged(Configuration newConfig)
    {
                // insert code here
    }
}

      

Learn more about the service fooobar.com/questions/428669 / ... .

0


source







All Articles