128 lines
4.3 KiB
Markdown
128 lines
4.3 KiB
Markdown
# Services - Remote
|
|
|
|
There is no communication between the two virtual address spaces.
|
|
|
|

|
|
|
|
When a service is bound to, Android will inspect the intent and find the relevant component to instantiate. If it doesn't exist/isn't running, it will create it. The service object that's created will return a binder object.
|
|
|
|
#### Remote Services
|
|
|
|
Making objects appear as if they exist in the local process - abstraction
|
|
|
|
- For communicating across process boundaries
|
|
- using a service belonging to a different application / process
|
|
- Handing off to **threads** in **different processes**
|
|
- Likely to be used by multiple processes at once
|
|
- Declare the service in the manifest
|
|
- Must not use implicit intents
|
|
- Doing something without the user's knowledge is problematic
|
|
- Examples like an MP3 player or location tracking do not need a remote service
|
|
- However, when using a service for downloading a file, multiple processes might want to use that and have access to progress. Another example is services that are drivers for hardware
|
|
- Communicating with it
|
|
- Using a messenger - preferred way ☑
|
|
- Defining an interface
|
|
- Registering callbacks
|
|
- Wrapping a system service in an API
|
|
|
|
#### Communicating with services
|
|
|
|
##### Via Messenger
|
|
|
|
What is a messenger?
|
|
|
|
- An IPC for a service
|
|
- Message-based communication between processes
|
|
- Asynchronous - technically but *feels* sequential
|
|
- Messages with bundles of data as payload instead of method calls
|
|
- Queues messages into a single thread, which are handled sequentially
|
|
- Allows a service to define a handler
|
|
- 'Has' an `IBinder` that is shared with the client
|
|
- Passed to the client on service connection
|
|
- Used to send messages to the service
|
|
- Bi-directional communication
|
|
- The client can have a messenger too
|
|
- Provide a reference to the return messenger in our message
|
|
- Sending a binder over a binder
|
|
|
|
#### Processes, Messengers and Handlers
|
|
|
|

|
|
|
|
##### Inter-process communication
|
|
|
|
`java.io.Serializable`
|
|
|
|
- Short-term persistence
|
|
- Write object ID and fields via reflection/introspection
|
|
- Brittle - If class/variable names are changed, it breaks
|
|
- It is slow
|
|
|
|
`Parcelable`
|
|
|
|
- Define a simple wire-protocol for writing primitives
|
|
- Re-create an object by passing salient data (deep copy)
|
|
- Immune to minor definition changes
|
|
- Supported by Android Kernel Driver
|
|
- Much faster
|
|
|
|
```java
|
|
public int x = 5;
|
|
public int y = 6;
|
|
public String text = "Martin";
|
|
// salient data is 5,6 & "Martin"
|
|
|
|
public void writeToParcel(Parcel out, int flags) {
|
|
out.writeInt(this.x);
|
|
out.writeInt(this.y);
|
|
out.writeString(this.text);
|
|
}
|
|
|
|
public void readFromParcel(Parcel in) {
|
|
this.x = in.readInt();
|
|
this.y = in.readInt();
|
|
this.text = in.readString();
|
|
}
|
|
```
|
|
|
|
We can change the class definition, e.g. add a private attribute `z` that we don't wish to communicate.
|
|
|
|
We can change the attribute names without anything breaking.
|
|
|
|
### Defining Remote Interfaces
|
|
|
|
Using the Android Interface Definition Language (AIDL)
|
|
|
|
- Specify an interface for the service functionality
|
|
- Generates a proxy object
|
|
- To be used locally as if the remote service was not remote
|
|
- Generates a sub implementation
|
|
- The remote side of the transaction
|
|
- Generates a communication protocol
|
|
- Parcelling and un-parcelling steps - a wire protocol for copying and recreating an object.
|
|
|
|
Similar to Java interface definitions
|
|
|
|
- Label method parameters for efficiency
|
|
- **in**: transferred to the remote method
|
|
- **out**: returned to the caller
|
|
- **inout**: both in and out
|
|
- **oneway**: asynchronous
|
|
- Permitted types
|
|
- Java primitive type: Lists, Maps, Other AIDL generated interfaces
|
|
- Classes implementing the Parcelable protocol
|
|
|
|

|
|
|
|
AIDL allows us to define something more complicated than just messages.
|
|
|
|
We define an interface, the IDE then generates a proxy object and a stub object, and also figures out how those two will communicate
|
|
|
|
We can then use calls on the proxy, which will delegate those calls into the stub object. We are responsible for implementing the methods in the stub object
|
|
|
|
### Binder abstraction
|
|
|
|

|
|
|
|
The binder driver can receive messages from multiple processes, so the service has to reason about receiving them
|