Ok, I'll explain in detail. There are two issues in this story: (a)
"killability" of the service (b) execution prio of the service

In the good old days I just
used  Process.setThreadPriority(Process.THREAD_PRIORITY_LOWEST) in my
service and things went wonderfully. My sync service ran and took as much
CPU was available, but the foreground app got all it needed too.

In rare cases my service was shot down, but as my service could deal with
that it was more a matter of efficiency than of data loss, so it was ok.

Progressively over time this happened more frequently though. With
information from you that we discussed on this list the story looked to me
like this: It became en vogue for many popular services to call
setForeground(). That lead to my services being shot down much more
frequently, to the point where it became really painful because my service
sometimes didn't even last for two seconds.

At the time I understood from what you said that I should consider calling
setForeground() and that you will make it no-op in a future release and at
the same time introduce a new API to replace the old one with the addition
that a notification needs to be shown, so that the user sees what's going on
and can punish apps that misuse this feature.

Now it took some time for me to get to the new API, because I need to
implement a useful notification first. To make the new notification useful I
rewrote my progress reporting, introduced remote views etc. to show the sync
phases and their progress in the notification. I also let the user set if
s/he wants to see the notification and get the added stability or not.

The old setForeground() only had an effect on the killability of the
process, but not on the scheduling priority. The priority I was then able to
set independently to low as I don't want to slow down the foreground app in
recognizing gestures or other stuff in the foreground that needs low
latency.

With the advent of startForeground() this doesn't work anymore, because
signaling in the foreground, killability and scheduling priority seem to
have been rolled into one.

It would be great if those things could be independently controlled like it
was possible before. And maybe it still is today? Process.setThreadPrio()
doesn't do the trick anymore though.

Don't get me wrong it is ok, when my activities sometimes get killed. If
there were API for that I would also let the OS know when I would prefer not
to (startCriticalSection()) and when it is cool to kill my activities.

As we are on the topic. It is not so cool to be just shot down. I would
prefer to get a signal that I am about to be shut down and get some time to
finish what I am doing in a grace period and then clean up (and save my
state). This would even be ok when this trigger would come earlier than the
OS actually absolutely needs to do it.

Ok, now back to your question. Let me give you two examples. One is not so
much of a problem today, I just try to explain what kind of uses I see, the
other one is what this thread is about.

(a) I store articles' metadata in a sqlite database in the phone memory and
the actual content (html, css, images) on the sd card.

As part of the sync some articles are removed. So I run over all articles
that are eligible for removal in the database. If I would get a signal to
clean up as outlined above I would break before I start deleting a new
article.

But back to what is implemented today. For each article I have to remove the
database record and the files on the sd card. The former is very fast, the
latter is slow.

It can happen that my process is suddenly killed in the middle of the
removal of an article. Hence I first removed the assets on the sd card, then
the database record. This way in the next sync I can clean up the rest and
only have the issue that between syncs (or restarts) some assets are missing
and articles are displayed with errors.

It would be *nicer* if I could invoke startCriticalSection() for the removal
of each article, but it's not a huge headache the way it is today.

(b) I sync with Google Reader and unfortunately the API doesn't support
incremental syncing for the most part. I have to fetch and parse an xml
stream that contains up to 10,000 ids (not that uncommon) during every sync,
write them to a temp database table and then set all articles in my database
to read for which I don't find their id in the temp database.

The issue is that if I need to retry that after my process had been killed I
have to fetch the xml stream with the 10,000 ids again. That is very
inefficient and wastes bandwidth, sync time, cpu and battery. And it gets
worse, this process can take say 20 seconds. So on the second and all
subsequent tries it may be shot down again. That's the reason I want this
part to have a lower kill prio then an actual foreground app/audio stream
from the background, but a higher kill prio than other background
activities, including the one I described in (a).

To give you another example: The Android download service. What I am writing
here is just from observations as user, I haven't looked at the API or the
code. (And I might be totally wrong, because I tried a couple of times to
download a video using the download service  and it never completed).

Anyway, some http servers allow retries, some don't, so for the later it
would be very unfortunate if the download process gets killed after 50 MB of
a 100MB file, because the download service would need to re-download the
50MBs after a restart again.

Now the download service sports a notification, so it may use the new API,
but that would clearly be wrong as it also boosts the scheduling prio which
is totally the wrong thing to do here as the download doesn't need low
latency at all. I just think it would not be a practical problem, because
downloads tend to be I/O bound almost 100% of the time. But I still hope you
see the picture I am trying to convey here?

Cheers,

Mariano

On Tue, Apr 13, 2010 at 1:05 AM, Dianne Hackborn <hack...@android.com>
wrote:

Why do you want to use startForeground()?  What is it giving you?  If you
want your code to run in the background, it is probably not what you want.

On Mon, Apr 12, 2010 at 2:04 PM, Mariano Kamp <mariano.k...@gmail.com>
wrote:

1) CPU is not a problem per se. My process can happily be starved of CPU,
but as it needs to do xml parsing it does task the CPU albeit at it's lowest
prio.

2) As I said I rely on an external API that doesn't understand incremental
updates.

Anyway, I think there is no good solution and the usefulness of this thread
is nearing zero now, so I will stop before I waste anymore of everybody's
time. Thanks so far.

On Mon, Apr 12, 2010 at 10:58 PM, Mark Murphy <mmur...@commonsware.com>
wrote:

 Mariano Kamp wrote:
>
>     Quoting myself:
>
> And you have done so wonderfully.
>
> What is it your trying to say though?
>
> That it is ok to raise the priority when I don't want my process to be
> killed.

I'm saying what Ms. Hackborn confirmed in her reply to my post --
startForeground() elevates the service's process to the foreground
priority class. The not-too-unreasonable assumption the SDK makes is
that something that is supposed to be in the foreground is supposed to
be in the foreground. I mean, "foreground" is in the method's name.
There's no question the documentation could be stronger, though.

That being said, your choices are:

1. Continue using startForeground() and either live with the complaints
or modify your service to be less CPU-intensive, or

2. Stop using startForeground() and modify your architecture to better
support the service being shut down

Since Android applications have to support their services being shut
down (via task killers, the Services screen in Settings, etc.), I would
think #2 would be the better answer, but that's your call.

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

Android Training in NYC: 4-6 June 2010: http://guruloft.com

--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com<android-developers%2bunsubscr...@googlegroups.com>
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

To unsubscribe, reply using "remove me" as the subject.

  --

You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com<android-developers%2bunsubscr...@googlegroups.com>
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en



-- 
Dianne Hackborn
Android framework engineer
hack...@android.com

Note: please don't send private questions to me, as I don't have time to
provide private support, and so won't reply to such e-mails.  All such
questions should be posted on public forums, where I and others can see and
answer them.

-- 

You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to android-developers@googlegroups.com
To unsubscribe from this group, send email to
android-developers+unsubscr...@googlegroups.com<android-developers%2bunsubscr...@googlegroups.com>
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en

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

Reply via email to