Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: service destroyed when display is rotated

I've got a service that is running in a separate process. I'm finding that after the main process UI thread exits from onDestroy() that my service is being destroyed even though I've provided the application context with the binding and specified BIND_AUTO_CREATE.

In my main process' UI thread onCreate() I've got this binding code:

Intent intent = new Intent(mAppContext, MyService.class);
mAppContext.bindService(intent, mMyServiceConnection, Context.BIND_AUTO_CREATE);

In my main process' UI thread onDestroy() I've got this unbinding code:

mAppContext.unbindService(mMyServiceConnection);

Note that I never call stopService().

Android's documentation for bindService() says:

The service will be considered required by the system only for as long as the calling context exists.

If I'm reading that correctly, because I supplied the application's context, the service is considered required by the system for the life of the application.

I have thought that maybe the application's context dies with onDestroy(). This is what Android's documentation says for getApplicationContext():

Return the context of the single, global Application object of the current process.

If the application's context dies with onDestroy(), then I think Android has a big issue. The issue is that when the display is rotated, onDestroy() is called (and immediately followed by onCreate()). Thus the effect is that when the display is rotated -- and it occurs quite frequently in my case! -- my service always exits.

Note that the pid of my app's process never changes, i.e. it is the same process. That is important in light of the documentation for getApplicationContext() stating "current process."

Here are what my debug logs show:

04-03 05:15:12.874: DEBUG/MyApp(841): main onDestroy
04-03 05:15:12.895: DEBUG/MyApp(847): service onUnbind
04-03 05:15:12.895: DEBUG/MyApp(847): service onDestroy
04-03 05:15:12.934: DEBUG/MyApp(841): main onCreate
04-03 05:15:12.966: DEBUG/MyApp(847): service onCreate
04-03 05:15:12.975: DEBUG/MyApp(847): service onBind

So my questions are:

1) Is my understanding about binding/unbinding correct?

2) Is there a way to have my service not get destroyed when UI thread's onDestroy() is called?

A hack for question #2 is to never unbind. But I don't like it because then I am leaking a binding every time onDestroy() is called. I could "remember" that I've got one leaked binding, and leak just that one, but then I've got cascaded hacks and it's real ugly.

like image 590
Syrinx Avatar asked Oct 11 '22 09:10

Syrinx


1 Answers

1) Yes, I think your understanding is correct (I say I think because I think I understand what you're saying ;-) ). The flag you are using means "start this service automatically if somebody tries to bind to it and keep it running as long as somebody is bound to it, but once nobody is bound to it, feel free to kill it".

2) Check out the START_STICKY flag as described here. That should allow you to start the service and keep it running regardless of what happens to the calling Context

In general, onDestroy() means your activity is about to be killed. When you rotate the display, the Activity is killed and recreated. You are responsible for saving any state to the Bundle in the appropriate method and then restoring it in onCreate().

like image 82
Chris Thompson Avatar answered Oct 23 '22 21:10

Chris Thompson