Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android how do I wait until a service is actually connected?

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?

like image 483
Ryan Avatar asked Jun 16 '10 17:06

Ryan


People also ask

How do I know if my Android service is 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.

What happens when you start a service in Android?

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() .


2 Answers

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.

like image 23
froman Avatar answered Sep 30 '22 23:09

froman


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().

like image 89
CommonsWare Avatar answered Sep 30 '22 23:09

CommonsWare