Added in API level 1

RemoteCallbackList


open class RemoteCallbackList<E : IInterface!>
kotlin.Any
   ↳ android.os.RemoteCallbackList

Takes care of the grunt work of maintaining a list of remote interfaces, typically for the use of performing callbacks from a android.app.Service to its clients. In particular, this:

  • Keeps track of a set of registered IInterface objects, taking care to identify them through their underlying unique IBinder (by calling IInterface.asBinder().
  • Attaches a IBinder.DeathRecipient to each registered interface, so that it can be cleaned out of the list if its process goes away.
  • Performs locking of the underlying list of interfaces to deal with multithreaded incoming calls, and a thread-safe way to iterate over a snapshot of the list without holding its lock.

To use this class, simply create a single instance along with your service, and call its #register and unregister methods as client register and unregister with your service. To call back on to the registered clients, use beginBroadcast, getBroadcastItem, and finishBroadcast.

If a registered interface's process goes away, this class will take care of automatically removing it from the list. If you want to do additional work in this situation, you can create a subclass that implements the #onCallbackDied method.

Summary

Nested classes

Builder for RemoteCallbackList.

Constants
static Int

When the callback recipient's process is frozen, callbacks are suppressed as if they never happened.

static Int

When the callback recipient's process is frozen, callbacks are enqueued so they're invoked after the recipient is unfrozen.

static Int

When the callback recipient's process is frozen, only the most recent callback is enqueued, which is later invoked after the recipient is unfrozen.

static Int

Callbacks are invoked immediately regardless of the frozen state of the target process.

Public constructors

Creates a RemoteCallbackList with FROZEN_CALLEE_POLICY_UNSET.

Public methods
open Int

Use instead to ensure proper handling of frozen processes.

open Unit
broadcast(callback: Consumer<E>)

Performs callback on each registered interface.

open Unit

Clean up the state of a broadcast previously initiated by calling beginBroadcast.

open Any!

Retrieve the cookie associated with the item returned by getBroadcastItem(int).

open E

Retrieve an item in the active broadcast that was previously started with beginBroadcast.

open Executor?

Returns the executor used when invoking callbacks asynchronously.

open Int

Returns the frozen callee policy.

open Int

Returns the max queue size.

open Any!

Return any cookie associated with a currently registered interface.

open Int

Returns the number of registered interfaces.

open E

Return a currently registered interface.

open Unit

Disable this interface list.

open Unit
onCallbackDied(callbackInterface: E)

Old version of onCallbackDied(E,java.lang.Object) that does not provide a cookie.

open Unit
onCallbackDied(callbackInterface: E, cookie: Any!)

Called when the process hosting an interface in the list has gone away.

open Boolean
register(callbackInterface: E)

Simple version of RemoteCallbackList.register(E, Object) that does not take a cookie object.

open Boolean
register(callbackInterface: E, cookie: Any!)

Add a new interface to the list.

open Boolean
unregister(callbackInterface: E)

Remove from the list an interface that was previously added with #register.

Constants

FROZEN_CALLEE_POLICY_DROP

static val FROZEN_CALLEE_POLICY_DROP: Int

When the callback recipient's process is frozen, callbacks are suppressed as if they never happened. This could be useful in the case where the recipient wishes to react to callbacks only when they occur while the recipient is not frozen. For example, certain network events are only worth responding to if the response can be immediate. Another example is recipients having another way of getting the latest state once it's unfrozen. Therefore there is no need to save callbacks that happened while the recipient was frozen.

Value: 3

FROZEN_CALLEE_POLICY_ENQUEUE_ALL

static val FROZEN_CALLEE_POLICY_ENQUEUE_ALL: Int

When the callback recipient's process is frozen, callbacks are enqueued so they're invoked after the recipient is unfrozen. This is commonly used when the recipient wants to receive all callbacks without losing any history, e.g. the recipient maintains a running count of events that occurred. Queued callbacks are invoked in the order they were originally broadcasted.

Value: 1

FROZEN_CALLEE_POLICY_ENQUEUE_MOST_RECENT

static val FROZEN_CALLEE_POLICY_ENQUEUE_MOST_RECENT: Int

When the callback recipient's process is frozen, only the most recent callback is enqueued, which is later invoked after the recipient is unfrozen. This can be used when only the most recent state matters, for instance when clients are listening to screen brightness changes.

Value: 2

FROZEN_CALLEE_POLICY_UNSET

static val FROZEN_CALLEE_POLICY_UNSET: Int

Callbacks are invoked immediately regardless of the frozen state of the target process. Not recommended. Only exists for backward-compatibility. This represents the behavior up to SDK 35. Starting with SDK 36, clients should set a policy to govern callback invocations when recipients are frozen.

Value: 0

Public constructors

RemoteCallbackList

Added in API level 1
RemoteCallbackList()

Creates a RemoteCallbackList with FROZEN_CALLEE_POLICY_UNSET. This is equivalent to

new RemoteCallbackList.Build(RemoteCallbackList.FROZEN_CALLEE_POLICY_UNSET).build()
  

Public methods

beginBroadcast

Added in API level 1
open fun beginBroadcast(): Int

Use instead to ensure proper handling of frozen processes. Prepare to start making calls to the currently registered interfaces. This creates a copy of the interface list, which you can retrieve items from using getBroadcastItem. Note that only one broadcast can be active at a time, so you must be sure to always call this from the same thread (usually by scheduling with Handler) or do your own synchronization. You must call finishBroadcast when done.

A typical loop delivering a broadcast looks like this:

int i = interfaces.beginBroadcast();
  while (i > 0) {
      i--;
      try {
          interfaces.getBroadcastItem(i).somethingHappened();
      } catch (RemoteException e) {
          // The RemoteCallbackList will take care of removing
          // the dead object for us.
      }
  }
  interfaces.finishBroadcast();
Note that this method is only supported for FROZEN_CALLEE_POLICY_UNSET. For other policies use broadcast(java.util.function.Consumer) instead.
Return
Int Returns the number of interfaces in the broadcast, to be used with getBroadcastItem to determine the range of indices you can supply.
Exceptions
java.lang.UnsupportedOperationException if an frozen callee policy is set.

broadcast

open fun broadcast(callback: Consumer<E>): Unit

Performs callback on each registered interface. This is equivalent to #beginBroadcast, followed by iterating over the items using #getBroadcastItem and then @finishBroadcast, except that this method supports frozen callee policies.

Parameters
callback Consumer<E>: This value cannot be null.

finishBroadcast

Added in API level 1
open fun finishBroadcast(): Unit

Clean up the state of a broadcast previously initiated by calling beginBroadcast. This must always be called when you are done with a broadcast.

See Also

getBroadcastCookie

Added in API level 4
open fun getBroadcastCookie(index: Int): Any!

Retrieve the cookie associated with the item returned by getBroadcastItem(int).

getBroadcastItem

Added in API level 1
open fun getBroadcastItem(index: Int): E

Retrieve an item in the active broadcast that was previously started with beginBroadcast. This can only be called after the broadcast is started, and its data is no longer valid after calling finishBroadcast.

Note that it is possible for the process of one of the returned interfaces to go away before you call it, so you will need to catch RemoteException when calling on to the returned object. The interface list itself, however, will take care of unregistering these objects once it detects that it is no longer valid, so you can handle such an exception by simply ignoring it.

Parameters
index Int: Which of the registered interfaces you would like to retrieve. Ranges from 0 to beginBroadcast-1, inclusive.
Return
E Returns the interface that you can call. This will always be non-null.

See Also

getExecutor

open fun getExecutor(): Executor?

Returns the executor used when invoking callbacks asynchronously.

Return
Executor? The executor. This value may be null.

getMaxQueueSize

open fun getMaxQueueSize(): Int

Returns the max queue size.

Return
Int The max queue size.

getRegisteredCallbackCookie

Added in API level 26
open fun getRegisteredCallbackCookie(index: Int): Any!

Return any cookie associated with a currently registered interface. Note that this is not the same as getBroadcastCookie and should not be used interchangeably with it. This method returns the current cookie registered at the given index, not the current broadcast state. This means that it is not itself thread-safe: any call to #register or unregister will change these indices, so you must do your own thread safety between these to protect from such changes.

Parameters
index Int: Index of which registration cookie to return, from 0 to getRegisteredCallbackCount() - 1.
Return
Any! Returns whatever cookie object is associated with this index, or null if kill() has been called.

getRegisteredCallbackCount

Added in API level 17
open fun getRegisteredCallbackCount(): Int

Returns the number of registered interfaces. Note that the number of registered interfaces may differ from the value returned by beginBroadcast() since the former returns the number of interfaces registered at the time of the call and the second the number of interfaces to which the broadcast will be delivered.

This function is useful to decide whether to schedule a broadcast if this requires doing some work which otherwise would not be performed.

Return
Int The size.

getRegisteredCallbackItem

Added in API level 26
open fun getRegisteredCallbackItem(index: Int): E

Return a currently registered interface. Note that this is not the same as getBroadcastItem and should not be used interchangeably with it. This method returns the registered interface at the given index, not the current broadcast state. This means that it is not itself thread-safe: any call to #register or unregister will change these indices, so you must do your own thread safety between these to protect from such changes.

Parameters
index Int: Index of which interface registration to return, from 0 to getRegisteredCallbackCount() - 1.
Return
E Returns whatever interface is associated with this index, or null if kill() has been called.

kill

Added in API level 1
open fun kill(): Unit

Disable this interface list. All registered interfaces are unregistered, and the list is disabled so that future calls to #register will fail. This should be used when a Service is stopping, to prevent clients from registering interfaces after it is stopped.

See Also

    onCallbackDied

    Added in API level 1
    open fun onCallbackDied(callbackInterface: E): Unit

    Old version of onCallbackDied(E,java.lang.Object) that does not provide a cookie.

    onCallbackDied

    Added in API level 4
    open fun onCallbackDied(
        callbackInterface: E,
        cookie: Any!
    ): Unit

    Called when the process hosting an interface in the list has gone away. The default implementation calls onCallbackDied(E) for backwards compatibility.

    Parameters
    callbackInterface E: The interface whose process has died. Note that, since its process has died, you can not make any calls on to this interface. You can, however, retrieve its IBinder and compare it with another IBinder to see if it is the same object.
    cookie Any!: The cookie object original provided to register(E,java.lang.Object).

    See Also

      register

      Added in API level 1
      open fun register(callbackInterface: E): Boolean

      Simple version of RemoteCallbackList.register(E, Object) that does not take a cookie object.

      register

      Added in API level 4
      open fun register(
          callbackInterface: E,
          cookie: Any!
      ): Boolean

      Add a new interface to the list. This interface will remain in the list until a corresponding call to unregister or its hosting process goes away. If the interface was already registered (determined by checking to see if the callbackInterface.asBinder() object is already in the list), then it will be replaced with the new interface. Registrations are not counted; a single call to unregister will remove an interface after any number calls to register it.

      Parameters
      callbackInterface E: The callback interface to be added to the list. Must not be null -- passing null here will cause a NullPointerException. Most services will want to check for null before calling this with an object given from a client, so that clients can't crash the service with bad data.
      cookie Any!: Optional additional data to be associated with this interface.
      Return
      Boolean Returns true if the interface was successfully added to the list. Returns false if it was not added, either because kill had previously been called or the interface's process has gone away.

      See Also

      unregister

      Added in API level 1
      open fun unregister(callbackInterface: E): Boolean

      Remove from the list an interface that was previously added with #register. This uses the callbackInterface.asBinder() object to correctly find the previous registration. Registrations are not counted; a single unregister call will remove an interface after any number calls to #register for it.

      Parameters
      callbackInterface E: The interface to be removed from the list. Passing null here will cause a NullPointerException, so you will generally want to check for null before calling.
      Return
      Boolean Returns true if the interface was found and unregistered. Returns false if the given interface was not found on the list.

      See Also