Search code examples
androidandroid-appwidget

AppWidget double update or static field?


I have an AppWidget that may receive two consecutive update request. To be shown it has to programmatically draw five 50x50 bitmaps, setting some PendingIntent and get some configuration (just to give you a little idea of the work load). It takes around 60 milliseconds between the two calls.

The option I have found so far to avoid the unnecessary update is to have a static field, something like:

public class myWidget extends AppWidgetProvider {

    private static long lastUpdate;

    @Override
    public void onReceive(Context context, Intent intent) {

        if((System.currentTimeMillis()-lastUpdate) > 200) {
            doUpdates(context);
        }
        lastUpdate = System.currentTimeMillis();

    }
}

With performance and "best practice" in mind...

Which do you think is the best solution in this case?

1) Use the static field (like in the example)

2) Just let the widget update twice

3) Other

In other words, is the use of the static field more harmful than just letting the widget update twice?


Solution

  • To be shown it has to programmatically draw five 50x50 bitmaps, setting some PendingIntent and get some configuration (just to give you a little idea of the work load). It takes around 60 milliseconds between the two calls.

    Note that this will cause your UI to drop frames if you happen to have your UI in the foreground at the time the update request(s) come in.

    Which do you think is the best solution in this case?

    Both #1 and #2.

    There is no guarantee that your process will still be around between the two subsequent update requests. Probably it will be around, given that you appear to be optimizing for two updates within 200ms. But it's not guaranteed. So, use the static data member for optimization purposes, but ensure that your code will survive the process being terminated in between.

    I'd suggest using SystemClock.elapsedRealtime(), though, instead of System.currentTimeMillis(). System.currentTimeMillis() is based on the real-time clock, which can be adjusted on the fly (e.g., NITZ signals, SNTP updates, user manually changing the clock). SystemClock.elapsedRealtime() is guaranteed to be monotonically increasing, and so it is a better choice for this sort of scenario. Only use SystemClock.elapsedRealtime() when you need to tie something to "real world" time (e.g., as part of work with Calendar objects), not for interval timing.