Android SDK


These pages provide documentation for Namespaces, Classes, Functions, and Variables within the MobiledgeX Android SDK.

Navigating the SDK Documentation

Use either the tabs or the treeview to find the desired page. There are two main sections: Classes and Modules. Classes will bring you to a list of all classes in the Android MobiledgeX SDK. Modules will bring you to a more organized breakdown of the Android SDK. The Modules are split up into Classes , Function Groups , and Exceptions . Each of these modules group similar classes, functions, or exceptions together. For example, all of the MatchingEngine API functions will be found under Modules -> Functions Groups -> MatchingEngine APIs.

Where to Start?

The main class that developers will be using is the com.mobiledgex.matchingengine.MatchingEngine class. This class provides functions to register the user to the Distributed Matching Engine, find the nearest application instance, and then get a connection to that application instance that is ready to be used (See diagram below for workflow). Go to the sections: MatchingEngine APIs and GetConnection Functions to get started.

How To

Project Setup

Create or open an existing Android Studio project.

Add these definitions to your project's top most build.gradle file. In the same directory, create a local.properties file with the artifactory username and password you use to log into https://console.mobiledgex.net. Create a login there, if you haven't already.

Properties properties = new Properties()
def artifactory_user = properties.getProperty("artifactory_user")
def artifactory_password = properties.getProperty("artifactory_password")

project.ext.mobiledgeXContextUrl = "https://artifactory.mobiledgex.net/artifactory"
project.ext.debugRepoKey = "maven-development"
project.ext.releaseRepoKey = "maven-releases"
project.ext.repoKey = "${debugRepoKey}"
project.ext.grpcVersion = '1.32.1'

Define a repository to pull these depedencies in, using the top most build.gradle file:

allprojects {
    apply plugin: 'com.jfrog.artifactory'
    repositories {
        maven {
            credentials {
                // Create these variables if you don't have them.
                username artifactory_user
                password artifactory_password
            url "${mobiledgeXContextUrl}/${repoKey}"

Add these depedencies to your app's build.gradle file:

implementation 'com.mobiledgex:matchingengine:3.0.0'
implementation 'com.mobiledgex:mel:1.0.11'
implementation 'com.google.guava:guava:29.0-android'

// Dependencies of Matching Engine:
implementation "io.grpc:grpc-stub:${grpcVersion}"

implementation "io.grpc:grpc-okhttp:${grpcVersion}"
implementation "io.grpc:grpc-protobuf-lite:${grpcVersion}"

With the dependencies defined, let Android Studio pull in the depedencies. To get started using MobiledgeX, you need a MatchingEngine instance. Since MatchingEngine needs location permissions, this might be reinitialized onResume():

Setup MatchingEngine

MatchingEngine me = new MatchingEngine(context);

For privacy reasons, there is a flag the application should ask the user for permission before enabling, concerning location usage. This is in addition to normal operating system permissions:


Then, register, and find the first closest cloudlet. If not sure of your organization or appInst details, log in and view the app details here: https://console.mobiledgex.net

Optionally, If interested in dynamic edge migration, you can enable it:

// Register the class subscribing to EdgeEvents to the EdgeEventsBus (Guava EventBus interface).
me.setEnableEdgeEvents(true); // default is true.

Setup EdgeEvents

Then, attach an EdgeEvents subscriber, described later in this document:

mEdgeEventsSubscriber = new EdgeEventsSubscriber();
// set a default config.
// There is also a parameterized version to further customize.
EdgeEventsConfig backgroundEdgeEventsConfig = me.createDefaultEdgeEventsConfig();
backgroundEdgeEventsConfig.latencyTestType = NetTest.TestType.CONNECT;
// This is the internal port, that has not been remapped to a public port for a particular appInst.
backgroundEdgeEventsConfig.latencyInternalPort = 0; // 3765; // 0 will favor the first TCP port if found for connect test.
// Latency config. There is also a very similar location update config.
backgroundEdgeEventsConfig.latencyUpdateConfig.maxNumberOfUpdates = 0; // Default is 0, which means test forever.
backgroundEdgeEventsConfig.latencyUpdateConfig.updateIntervalSeconds = 7; // The default is 30.
backgroundEdgeEventsConfig.latencyThresholdTrigger = 186;

Note that there are 2 configurations set. A application should use only one config, after deciding between performance testing (latencyUpdateConfig), or proximity based (locationUpdateConfig) newCloudlet updates. To use LocationUpdateConfig, where server pushes newCloudlet updates, simply set latencyUpdateConfig = null.

Once defined, you can start monitoring with the following. Monitoring starts when the first successful FIND_FOUND FindCloudlet Reply is returned in the next few lines of code.


Register and FindCloudlet

Many of these methods have asynchronous Futures versions. The blocking versions below should only be run inside something like a CompletableFuture so that the UI thread is not stuck waiting for a network response. The SDK will also print warnings if running on the UI thread. If you don't have a location service running, see the "Location Callback Example" section.

Create a register client request:

AppClient.RegisterClientRequest registerClientRequest = me.createDefaultRegisterClientRequest(context, organizationName).build();

Register, with a sane timeout, like 5 seconds.

registerReply = me.registerClient(registerClientRequest, GRPC_TIMEOUT_MS);

Create a default FindCloudlet Request:

AppClient.FindCloudletRequest findCloudletRequest = me.createDefaultFindCloudletRequest(context, location)

FindCloudlet, with a sane timeout, like 5 seconds.

findCloudletReply1 = me.findCloudlet(findCloudletRequest, GRPC_TIMEOUT_MS);

Connect to the Edge AppInst

To connect to the edge server instance, use something similar to the following:

if (findCloudletReply1.getStatus() == AppClient.FindCloudletReply.FindStatus.FIND_FOUND) {
// The edge server host and port can be constructed with the following utility code:
String host = me.getAppConnectionManager().getHost(findCloudletReply1, internalAppInstPortNum);
int port = me.getAppConnectionManager().getPublicPort(findCloudletReply1, internalAppInstPortNum);
Log.i(TAG, "Host: " + host + ", Port: " + port);

EdgeEventsSubscriber Template

Here is the EdgeEventsSubscriber class mentioned near the start of the document. The following example code is a Guava EventBus type Subscriber to EdgeEvents. onMessageEvent can be any name as the EventBus will forward it to the matching class type. The FindCloudletEvent variant is good to subscribe in your application. When recieved, the app should save state, and move to the next closer cloudlet.

// (Guava EventBus Interface)
// This class encapsulates what an app might implement to watch for edge events. Not every event
// needs to be implemented. If you just want FindCloudlet, just @Subscribe to FindCloudletEvent.
class EdgeEventsSubscriber {
// Subscribe to error handlers!
public void onMessageEvent(EdgeEventsConnection.EdgeEventsError error) {
Log.d(TAG, "EdgeEvents error reported, reason: " + error);
someText = error.toString();
updateText(ctx, someText);
// Check the App's EdgeEventsConfig and logs.
// Subscribe to FindCloudletEvent updates to appInst. Reasons to do so include
// the AppInst Health and Latency spec for this application.
public void onMessageEvent(FindCloudletEvent findCloudletEvent) {
Log.i(TAG, "Cloudlet update, reason: " + findCloudletEvent.trigger);
// Connect to new Cloudlet in the event here, preferably in a background task.
Log.i(TAG, "Cloudlet: " + findCloudletEvent.newCloudlet);
someText = findCloudletEvent.newCloudlet.toString();
updateText(ctx, someText);
// If MatchingEngine.setAutoMigrateEdgeEventsConnection() has been set to false,
// let MatchingEngine know with switchedToNextCloudlet() so the new cloudlet can
// maintain the edge connection.
// Subscribe to ServerEdgeEvents!
// Optional. If you set this event handler, the app will take ownership of raw
// events off the EdgeEventBus so a custom handler can be written in to fit your application
// use case better.
// To optionally post messages to the DME, use MatchingEngine's EdgeEventsConnection.
public void onMessageEvent(AppClient.ServerEdgeEvent event) {
someText = event.toString();
updateText(ctx, someText);
switch (event.getEventType()) {
System.out.println("Received Init response: " + event);
System.out.println("Received: AppInst Health: " + event);
System.out.println("Received: Cloutlet State event: " + event);
System.out.println("Received: Cloutlet Maintenance event." + event);
System.out.println("Received: Latency has been processed on server: " + event);
System.out.println("Received: Latency has been requested to be tested (client perspective): " + event);
System.out.println("Received: Server pushed a new FindCloudletReply to switch to: " + event);
Log.d(TAG,"Received: An edgeEvents error: " + event.getErrorMsg());
System.out.println("Received UnknownEvent.");
System.out.println("Event Received: " + event.getEventType());

Location Callback Example and Posting Updates for Cloudlet Updates

It is possible to directly feed location into the EdgeEvents connection to the server. If there is a closer edge server, the app will be notified about a better cloudlet. Location permissions is app controled, as the app UI controls permission prompts between onPause() and onResume() states, where the the user might remove location permisisons.

mLocationCallback = new LocationCallback() {
public void onLocationResult(LocationResult locationResult) {
if (locationResult == null) {
String clientLocText = "";
mLastLocationResult = locationResult;
// Post into edgeEvents updater:
.thenApply(connection -> {
if (connection != null) {
return null;
for (Location location : locationResult.getLocations()) {
// Update UI with client location data
clientLocText += "[" + location.toString() + "]";
TextView tv = findViewById(R.id.client_location_content);

To request android location service to run in the background, you need google play services, please read here: https://developer.android.com/training/location/request-updates#java

MatchingEngine Permission Utility

The application should prompt for location permissions, as well as read the network state for edge server state management. Here's example to check using com.mobiledgex.matchingengine.util.RequestPermissions. It has getNeededPermissions() to check current missing permissions. Be sure to add needed permissions to the app's AndroidManifest.xml file. Be sure to include INTERNET permissions.

mRpUtil = new RequestPermissions();
// As of Android 23, permissions can be asked for while the app is still running.
if (mRpUtil.getNeededPermissions(appCompatActivity).size() > 0) {


Managing Resources

If the application onPause() is called, consider calling stopEdgeEvents() to free resources. Re-enable at onResume().

Managing Resources

When the app needs to quit or free resources, call close():

public void onDestroy() {
if (me != null) {
me = null;
mEdgeEventsSubscriber = null;
ctx = null;