开发者

Keeping an AsyncTask alive in low memory conditions?

I have written a home screen widget as an ImageView, ie. the code generates the whole widget and writes it to RemoteViews as a bitmap. On slower devices with low memory, such as my G1, it can take a couple of seconds to generate the bitmap, and to avoid the dreaded force-close, I moved all the graphics code into an AsyncTask. So far so good.

However, in very low memory conditions, the AsyncTask can easily be killed by the OS before it has finished generating the bitmap, resulting in an empty square on the homescreen. So before creating the AsyncTask, it sets an alarm for now + 5 seconds, and after the graphics are complete, it resets the alarm. The assumption here is that if the alarm is triggered, more than likely the process was killed, and we have to set another now+5 alarm and start again.

This does work, but in extreme low memory conditions it can take several attempts (20+ seconds) to draw the widget, so I added a placeholder hourglass image, as a static resource, which is displayed on the homescreen until the real image is ready.

My question is this: is this the best way? Is there some way to (politely) ask the OS not t开发者_Go百科o kill the AsyncTask until it's finished (on the grounds that killing it will actually result in more waste of system resources)?

I understand that if a process is categorised as "visible" then Android won't kill it except as a last resort. But I don't know how to tag an AsyncTask as "visible". I'm very happy for the process to be killed just as soon as it's done drawing the widget. Would just like it to stay alive long enough to complete.


Use an EmptyService by binding to it and unbinding once the work is done, see https://github.com/android/platform_packages_providers_calendarprovider/blob/master/src/com/android/providers/calendar/EmptyService.java. I'm not sure if this guarantees that you're process won't be killed or if simply reduces the chances of it being killed.

You can also use a foreground service but you'll have to supply it with a status bar notification, see http://developer.android.com/guide/components/services.html#Foreground.

Or you can use IntentService as @Mike suggested; although I can't see in the documentation that "it gets the same kill priority as a foreground task".


Have you considered using an IntentService for this? While your service code is executing it gets the same kill priority as a foreground task. It won't have quite the tight coupling to the widget that an AsyncTask would, but I think it would increase the odds of your code finishing.


try to use Service class, you can set service as "Foreground". There are probably near to zero chances getting Foreground service closed.

Also,Service does same as Async.

As soon as you are done with the work,then close the service.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜