Android Inter-Process Communication (IPC) — it’s biggest limitation?
This article is not meant to introduce the reader to Inter-process communication (IPC) is or how IPC can be used in Android OS. But this is only meant to serve as a motivation that leads to some work presented in the paper here. Also, visit my other post here on using IPC for developing distributed Android Apps.
What is IPC?
Inter-process communication mechanisms are provided by operating systems to allow processes to share information, e.g., for signalling or for managing data between processes. Applications often distribute their tasks into multiple processes (e.g., for improved performance, modularity) and use IPC mechanisms offered by the OS for exchanging application data between their processes, depending on their requirements.
An operating system may provide more than one type of IPC, designed specifically for different process communication or software requirements. Such requirements include any combination of; the number of communication entities (one-to-one vs one-to-many), performance, modularity, communication type/model (e.g., synchronous vs asynchronous).
Android IPC
Every application in android are started in one android process, isolating its execution and data from other applications running in the same device. This not only allows applications to sepearte its data in both persistent and non-persistant storages, but also ensures that the performance of the application is not hindered by other applications and services that runs parallel to it. However, parts of applications can be executed in other processes, for improved performance, security, modularity and data isolation.
Like most operating systems, Android offers a number of IPC mechanisms. Each designed for satisfying varying requirements (Intent, Android Interface Definition Language [AIDL], Binder). Although, developers can use conventional linux IPC within Android (such as network sockets and shared files), Android recommends you to use Android’s own IPC mechanisms that are designed specifically to suite mobile applications and Android resource/process and security management (see the official documentation).
Limitations
At the heart of Android IPC is the Binder driver, a Remote Procedures Call mechanism (RPC) which facilitates Android IPC mechanisms. Binder provides additional functionalities that traditional linux/POSIX IPC do not have (e.g., data referencing, file passing). As can be seen in Figure 1 below, binder serves as the core component of Android IPC, a kernel driver used by all other IPC types (i.e., Intent, AIDL), including the IBinder interface which can be used to use Binder IPC.
Therefore, by design, Binder becomes a bottleneck for all IPC communication. Specifically, bandwidth and latency limitations imposed by binder becomes even more prominent as the level of abstraction increases. Although, Android do not disclose specific resource limitations of Binder and Android IPC, it is common knowledge and recommendation that they are not used for transferring large payloads.
Moreover, as can be seen in Figure 2, the memory footprint, CPU usage, and latency of Android IPC message transfers increases significantly for large payloads, rendering them unusable for anything beyond signalling or simple text message transfers among android application components, and not suitable for payloads of useful sizes.
Figure 3 shows how continuous transferring of relatively large payloads over Android IPC (Intent), rapidly increase the memory footprint until the application consumes all the memory allocated for its process, causing the applications to slow down and crash (if the corresponding exceptions are not handled). Such high bandwidth communication are not considered as a requirement for Android IPC and they are currently used rather extensively and efficiently throughout the Android OS. However, with the increased popularity of more complex applications with various new processing components that are often resource intensive (ML, data analytics), the ability to modularize components more flexibly (despite the degree of data dependency) and distribute them more efficiently becomes crucial. Distributing their loads (e.g., in multiple processes) and enabling them to communicate efficiently (using IPC to communicate [often data that can be relatively large in size]) between them (e.g., following microservices application structuring model) may not only improve the overall performance of applications, but may also enable application developers to use new and more flexible means of application structuring/modularisation/workload distribution, supported by efficient and flexible inter-app and intra-app communication mechanisms.
Conclusion
Android provides various IPC mechanisms to be used for exchanging messages and managing data between application components. Android IPC mechanisms use Binder driver as its core communication component, different IPC providing various abstractions to developers, on top of Binder capabilities. Binder is not designed for communicating large payloads, therefore, limiting all other Android IPC communications to IPC messages much smaller payloads. Therefore, if IPC mechanisms to be used for much advanced and complex application scenarios (ones that use IPC not only for signalling but also for transferring application data), e.g., continuous sensing, data analytics, ML processing applications (ones that require transmission of large payloads between application components/processes), current android IPC mechanisms must be improved, or new mechanisms must be introduced to enable high bandwidth and low latency data transmissions among application components.