About Binder Caching
There was a debate earlier in the week on the android-developers
Google Group
regarding the behavior of onBind()
in a service. While the original question was whether two
clients can both be bound to a remote service (answer: yes), a sidebar developed regarding
onBind()
and caching.
Something I had not realized, until Kostya Vasilyev pointed it out, is that Service
caches
the object returned by onBind()
for a given Intent
. In other words, the second
and subsequent times that a running Service
is bound to, onBind()
will not be called,
if the Intent
used each time is equivalent. Here, “equivalent” means that the action,
data (Uri
), categories, and MIME type are identical.
If, however, you use different Intent
structures, such as different action strings,
that will result in onBind()
being called multiple times, one for each distinct
Intent
.
This is important for remote service binding. The contract between your Service
and third-party
developers is not really the Service
itself, but a specific Binder
structure, described
via AIDL. Ideally, you should use an <intent-filter>
with a custom action string as your
public stable name for that Binder
/AIDL structure, so you can refactor class implementations
without breaking the effective public API. However, if you decide that you need a new Binder
(e.g., add new methods), you can use a different action string, and have onBind()
return
the right Binder
based on the received action. This way, you can support both old and new
versions of your Binder
/AIDL API simultaneously.
If onBind()
caching was oblivious to the changes in Intent
, then this would not work —
the first onBind()
call would return whatever Binder
it needed, and everybody else would wind
up with that same Binder
, like it or not. However, I can confirm that onBind()
caching
does respect the Intent
contents, and so the multiple-action-string pattern should work just fine.