A library for building Flutter plugins that want to maintain access to object instances on separate threads/processes.


This library works by managing pairs of references. Each pair consists of a LocalReference and a RemoteReference. The pairs are stored and managed in a ReferencePairManager. Here are the basic definitions of these classes:

  • LocalReference - represents an object on the same thread/process.
  • RemoteReference - represents an object on a different thread/process.
  • ReferencePairManager - manages communication between objects represented by LocalReferences and RemoteReferences.

A LocalReference and RemoteReference pair is also maintained by a pair of ReferencePairManagers. One ReferencePairManager is on the same thread/process as the object that LocalReference represents and another ReferencePairManager is on the same thread/process as the object that RemoteReference represents.

The labels of local and remote are relative to which thread one is on. A RemoteReference in a ReferencePairManager will represent a LocalReference in another ReferencePairManager and vice versa. This is shown in the diagram below:

Reference Architecture

It’s also important to note that the RemoteReference in both ReferencePairManagers are considered equivalent values, so they can be used to identify paired LocalReferences.

For every reference pair, the ReferencePairManager’s role is to handle communication between the objects represented by LocalReference and RemoteReference.

How ReferencePairManager Handles Communication

ReferencePairManagers are responsible for creating pairs, disposing pairs, and calling methods on paired References. Here are the relevant classes:

  • TypeReference - represents a type. This type must be able to be represented by a LocalReference.
  • RemoteReferenceCommunicationHandler - handles communication with RemoteReferences for a ReferencePairManager. This class communicates with other ReferencePairManagers to create, dispose, or execute methods on RemoteReferences.
  • LocalReferenceCommunicationHandler - handles communication with LocalReferences for a ReferencePairManager. This class handles communication from other ReferencePairManagers to create, dispose, or execute methods for a LocalReference.

Below is the typical flow for either creating a pair, disposing of a pair, or a LocalReference calling a method on it’s paired RemoteReference. A detailed example follows.

Reference Architecture

To give a more detailed explanation, let’s assume we want to create a new pair. It’s also important to remember that what is considered a LocalReference to one ReferencePairManager, is considered a RemoteReference to another.

  1. An instance of LocalReference is created.
  2. LocalReference tells ReferencePairManager1 to create a RemoteReference.
  3. ReferencePairManager1 creates a RemoteReference and stores the RemoteReference and the LocalReference as a pair.
  4. ReferencePairManager1 tells its RemoteReferenceCommunicationHandler to communicate with another ReferencePairManager to create a RemoteReference for the instance of LocalReference.
  5. RemoteReferenceCommunicationHandler tells ReferencePairManager2 to make a RemoteReference.
  6. ReferencePairManager2 tells its LocalReferenceCommunicationHandler to create a LocalReference.
  7. LocalReferenceCommunicationHandler creates and returns a LocalReference.
  8. ReferencePairManager2 stores the RemoteReference and the LocalReference from LocalReferenceCommunicationHandler as a pair.

How ReferencePairManager Handles Arguments

When creating a RemoteReference or executing a method, you have the option to pass arguments as well. Before a ReferencePairManager hands off arguments to a RemoteReferenceCommunicationHandler, it converts all LocalReferences to RemoteReferences and before a ReferencePairManager hands off arguments to a LocalReferenceCommunicationHandler it converts all RemoteReferences to LocalReferences.

Getting Started

This project is a starting point for a Flutter plug-in package, a specialized package that includes platform-specific implementation code for Android and/or iOS.

For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.

To use this with your own plugin, you will have to extend ReferencePairManager and implement RemoteReferenceCommunicationHandler and LocalReferenceCommunicationHandler. This needs to be done in Dart and then on every platform that is wanted to be supported. (e.g. Java/Kotlin for Android or Obj-C/Swift for iOS. This plugin allows you to use any system for IPC (e.g. MethodChannel or dart:ffi), but it also provides a MethodChannelReferencePairManager that is a partial implementation using MethodChannels. Here are the latest example implementations for Dart and Java.