whitemice wrote:
> I have "Call Log Widget" on the Android Market:
> http://blog.zedray.com/call-log-widget/
> 
> The core of this Widget is an AppWidgetProvider which registers a
> ContentObserver to the CallLog content URI.  This means that my widget
> is updated every time a call (incoming, outgoing, missed) is
> recorded.  This works fine for a while, until *something happens* and
> my ContentObserver stops getting called (no error message seen in
> trace).  I would rather that this ContentObserver persisted until the
> user removes the Widget.

I am surprised that it works at all.

An AppWidgetProvider is a manifest-registered BroadcastReceiver. Those
are supposed to be very transient. You cannot safely register listeners,
fork threads, etc. from an AppWidgetProvider. You will leak memory for a
while, then Android will give your process the heave-ho.

> I am guessing that my JVM has been destroyed (due to low memory?),

More likely your process is being recycled for use by something else,
which should flush the JVM.

> I can hide this bug by periodically re-registering my Content
> provider, but I would rather understand the cause and have a more
> optimal solution.

The best answer is for you to not use a ContentObserver and to adopt a
polling pattern, with a nice slow default polling period (e.g., once
every 30 minutes) and user control over that polling period:

http://www.androidguys.com/2010/03/29/code-pollution-background-control/

The next-best answer is for your ContentObserver to be registered in a
Service that gets started by the AppWidgetProvider, since Services are
designed to hang around a bit longer. However, this means you are trying
to have an everlasting service, and that's not really going to work --
eventually, the user will kill it off (via Settings application or a
task killer) or Android will kill it off:

http://www.androidguys.com/2009/09/09/diamonds-are-forever-services-are-not/

Plus, of course, while your service is running, you're tying up a chunk
of RAM which might have better uses. The polling approach means your
code can stay out of memory most of the time, except when you're looking
for new calls.

You may be able to work something out with an "event-driven poll",
watching for ACTION_PHONE_STATE_CHANGED, and polling the call log after
the phone call has ended. The tricky part is ensuring that the call is
in the log by the time you go looking for it. However, if you can work
that out, you get the best of both worlds: near-immediate updates while
avoiding the ContentObserver and keeping your code out of RAM most of
the time.

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

Warescription: Three Android Books, Plus Updates, One Low Price!

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

Reply via email to