I have an Activity calling a Service defined in IDownloaderService.aidl:
public class Downloader extends Activity { IDownloaderService downloader = null; // ...
In Downloader.onCreate(Bundle) I tried to bindService
Intent serviceIntent = new Intent(this, DownloaderService.class); if (bindService(serviceIntent, sc, BIND_AUTO_CREATE)) { // ...
and within the ServiceConnection object sc I did this
public void onServiceConnected(ComponentName name, IBinder service) { Log.w("XXX", "onServiceConnected"); downloader = IDownloaderService.Stub.asInterface(service); // ...
By adding all kinds of Log.xx I found that the code after if(bindService(...)) actually goes BEFORE ServiceConnection.onServiceConnected is being called - that is, when downloader is still null - which gets me into trouble. All the samples in ApiDemos avoid this timing problem by only calling services when triggered by user actions. But what should I do to right use this service after bindService succeeds? How can I wait for ServiceConnection.onServiceConnected being called reliably?
Another question related. Are all the event handlers: Activity.onCreate, any View.onClickListener.onClick, ServiceConnection.onServiceConnected, etc. actually called in the same thread (mentioned in the doc as the "main thread")? Are there interleaves between them, or Android would schedule all events come into being handled one-by-one? Or, When exactly is ServiceConnection.onServiceConnected actually going to be called? Upon completion of Activity.onCreate or sometime when A.oC is still running?
You can do this by making your own Interface where you declare for example " isServiceRunning() ". You can then bind your Activity to your Service, run the method isServiceRunning(), the Service will check for itself if it is running or not and returns a boolean to your Activity.
A started service must manage its own lifecycle. That is, the system doesn't stop or destroy the service unless it must recover system memory and the service continues to run after onStartCommand() returns. The service must stop itself by calling stopSelf() , or another component can stop it by calling stopService() .
I had the same problem. I didn't want to put my bound service dependent code in onServiceConnected
, though, because I wanted to bind/unbind with onStart
and onStop,
but I didn't want the code to run again every time the activity came back to the front. I only wanted it to run when the activity was first created.
I finally got over my onStart()
tunnel vision and used a Boolean to indicate whether this was the first onServiceConnected
run or not. That way, I can unbindService in onStop
and bindService again in onStart
without running all the start up stuff each time.
How can I wait for ServiceConnection.onServiceConnected being called reliably?
You don't. You exit out of onCreate()
(or wherever you are binding) and you put you "needs the connection established" code in onServiceConnected()
.
Are all the event handlers: Activity.onCreate, any View.onClickListener.onClick, ServiceConnection.onServiceConnected, etc. actually called in the same thread
Yes.
When exactly is ServiceConnection.onServiceConnected actually going to be called? Upon completion of Activity.onCreate or sometime when A.oC is still running?
Your bind request probably is not even going to start until after you leave onCreate()
. Hence, onServiceConnected()
will called sometime after you leave onCreate()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With