2

In an Android app, I need several listeners (for network changes, location changes, etc.).

As far as I can see, these are called in a thread (or threads) which are not my main background service thread. (I'm creating a service-only app.)

My question is:

Can my app be hit by listeners firing simultaneously, or does Android mitigate this by invoking my listeners in a single thread?

Secondly, if the listeners aren't 'sequentialised', are the individual listeners re-entrant?

In other words, can I carry out complex processing in my listeners, or should they just dump what happened into a synchronized list, for later processing my background service thread (and wakeup the background service thread from its sleep while they're at it).

There seems to be very little coverage of thread synchronisation in Android example docs and books.

Thanks,

Chris.

fadedbee
  • 42,671
  • 44
  • 178
  • 308

1 Answers1

4

I don't know what types of listeners you're talking about specifically, but generally they are not called on their own threads. They are called on the thread that you register the listener on, so if you register the listener on the UI thread it will fire on the UI thread. If you create a Looper thread, then you can register listeners on that thread, and they will fire in that thread sequentially as they hit.

DeeV
  • 35,865
  • 9
  • 108
  • 95
  • If this is just a Service (no Activities) is the thread which calls the service's onCreate and onStart the 'UI' thread? (Even though there is no 'UI'.) – fadedbee Jan 18 '12 at 15:31
  • 1
    That's correct. People tend to use UI thread when they mean main thread, but its all the same. – Justin Breitfeller Jan 18 '12 at 15:35
  • 1
    Yeah, sorry. UI thread and Main thread are synonymous. Services run on the main/UI thread, so everything that happens in them affects all other programs. – DeeV Jan 18 '12 at 15:39
  • Where did you find the info that _[listeners] are called on the thread that you register the listener on_ ? Just curious - and links to docs are appreciated ;) – Mr_and_Mrs_D Nov 13 '13 at 03:10
  • 1
    @Mr_and_Mrs_D: I wrote this nearly two years ago, so I'm trying to remember the context I was thinking back then. I admit the wording is very bad, so I'm thinking my understanding back then was off. Basically, the listeners he was referring too must be called is `Looper` threads. The UI is one massive `Looper` thread, basically. A Looper keeps the thread alive which keeps the Listener object alive. http://stackoverflow.com/questions/11129925/onlocationchanged-callback-is-made-on-what-thread-the-main-ui-thread – DeeV Nov 13 '13 at 03:34
  • Rough example of a Looper: http://developer.android.com/reference/android/os/Looper.html – DeeV Nov 13 '13 at 03:35
  • So if I register a listener in my service (say an intent service that runs on its own thread) and then do `latch.await()` the listener will never be called correct ? I am not quite sure I get where the Looper fits in – Mr_and_Mrs_D Nov 13 '13 at 16:18
  • Actually I remember an answer that more fully explains Looer mechanism. http://stackoverflow.com/questions/10403858/java-cant-create-handler-inside-thread-that-has-not-called-looper-prepare/10404099#10404099 – DeeV Nov 13 '13 at 18:52
  • But anyway, Android uses `Handlers` to pass messages between threads. They are also used to execute code in threads. In a lot of cases, like `LocationListener`, Android will use a `Handler` to send an event to the Listener. `Looper` is the mechanism that keeps threads alive in order for the objects to work. You'll very often get an exception like the one in the answer just linked if Android tries to call a Handler that's not in a Looper thread. – DeeV Nov 13 '13 at 18:56
  • I should also note that IntentService is not intended to be a long-standing thread. Android queues `IntentService` together so they run sequentially. If you keep on alive, the others will never get called. A better (and only really), is to create a `Service` and start your own long-standing thread. – DeeV Nov 13 '13 at 19:03