0

I have an application that uses a service for some of its functions.

One of my calls to the service is called from onResume and therefor I needed to make sure the service was connected before calling it.

I used the answer from this question is there a 'block until condition becomes true' function in java? to put a synchronized block just before calling the method from my service, with a syncObject.wait() command, and to release it, I placed another synchronized block with syncObject.notifyAll() in the onServiceConnected method.

What happend is that after getting to the syncObject.wait() call, the application just hung, waiting forever. Not only the the syncObject.notify() was never reached, the onServiceConnected method was not even called.

Removing the synchronized block solved the issue, but that would mean that I'll have to put the call to the service method inside onServiceConnected(), which is problematic in my case (there are conditions in onResume that will determine if that part of the code should be executed or not)

Note: I do already have a solution for it, but it's sort of a workaround and I would really just like to put a line that blocks the code, until the service is connected.

Community
  • 1
  • 1
Tom Klino
  • 2,358
  • 5
  • 35
  • 60

1 Answers1

0

One of my calls to the service is called from onResume and therefor I needed to make sure the service was connected before calling it.

You do not have control over the timing of service binding with respect to any other lifecycle methods.

What happend is that after getting to the syncObject.wait() call, the application just hung, waiting forever. Not only the the syncObject.notify() was never reached, the onServiceConnected method was not even called.

onResume() and onServiceConnected() are both called on the main application thread. Hence, you cannot block in one waiting for the other to occur.

but that would mean that I'll have to put the call to the service method inside onServiceConnected(), which is problematic in my case (there are conditions in onResume that will determine if that part of the code should be executed or not)

Alter your code to do the work triggered by either onResume() or onServiceConnected(), whichever occurs last.

You might also wish to reconsider whether a bound service is appropriate for your use case.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • As I said I already have a solution to the issue (putting the code block a a Runnable in a Queue and iterating over the Queue in onServiceConnected). But I still wish to know if there is a way to put a line that tells the program to wait there until the service is connected. Also, the android developer guide states that calling the bindService is asynchrounous. How could it be asynchrounous and still be on the same thread? – Tom Klino Jul 04 '14 at 16:27
  • @Tom: "But I still wish to know if there is a way to put a line that tells the program to wait there until the service is connected" -- as I pointed out, that is not possible. "How could it be asynchrounous and still be on the same thread?" -- the call to `bindService()` is asynchronous. The *results of `bindService()`*, in the form of the callback to your `ServiceConnection`, are delivered to you on the main application thread. This is no different than how `AsyncTask`, `Handler`, event buses, etc. work. – CommonsWare Jul 04 '14 at 16:56