Android is Linux base operating system and one of one of the key principles of Linux is the separation between processes. So what happens when you want to cross the boundaries.  

Services

In Android a service is an application component that can run long running operation without providing  UI. Services are used to do long running tasks like retrieving data from remote servers or retrieving large-size data from memory. Services -usually- run in the same process but never on the same thread as UI as executing long running tasks on UI thread would lead to blocking the UI responsiveness to user's actions and “application not responding” dialogs that will most certainly lead to bad user experience and app uninstall along the way.

A service starts in the application process as all other application components by default so what happen when a developer wants to expose  application's services so they can be used by other applications. 

There are multiple approaches to calling a remote service we can consider using broadcast&receivers and AIDL (Android Interface Definition Language).

Broadcast&Receivers

A Broadcast receiver is an application component that listen for system events as well as application events. By definition a broadcast is transferring a message to all recipients simultaneously (one-to-all). Using a Broadcast receivers for communication with a remote service there is a couple of things needs to be taken into  consideration:

1- the maximum size of the ”Bundle” message in the Intents used to send broadcast.
If the arguments or the return value are too large to fit in the transaction buffer, then the transaction will fail and throw TransactionTooLargeException. Generally its prefered to keep message size under 1MB as it is the maximum if transaction buffer till now.

2- A broadcast is transmitted across the system and that could introduce a security threat.
Other apps can listen to broadcasts and use it for any other purpose. As a rule of thumb any sensitive data should not be broadcasted.

AIDL

AIDL is allows developers to expose their services to other application by means of defining of programming interface that both the client and service agree upon in order to communicate with each other. AIDL achieves IPC by marshaling(Marshaling is the process of transforming the memory representation of an object to a data format suitable for storage or transmission. A note worth taking is that marshaling parameters is expensive) the objects. The programming interface contains the methods that other processes should use to communicate with this service. Methods accept parameters and return results in the following  data types:

1. All primitive types in the Java programming language (such as int, long, ,.....).
2. String.
3. CharSequence.
4. List (with a restriction).
5. Map (with a restriction).


The restriction on Map and List is that all elements in them must be one of the supported data types or one of the other AIDL-generated interfaces or declared Parcelables. 

The .aidl file must be copied to other applications in order for them to communicate with the service remotely so when any change is made in AIDL interface after the is service release must keep  backward compatiblity in order to avoid breaking other applications that are already using your service.

A hint mentioned in the Android API guide tells us to be aware that calls to an AIDL interface are direct function calls.  And no assumptions should be made about the thread in which the call occurs. A pure AIDL interface sends simultaneous requests to the service, which must then handle multi-threading.

AIDL vs Broadcast&Receivers

AIDL does IPC through marshaling, executes call simultaneously and require writing thread-safe code on the other hand we have got broadcast, an intent based communication with limited size message imposing security threat on sensitive information.