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