Native Android UI

Use built-in Android library UI components

Loading and Drawing Native Android UI

We provide support for the loading and drawing of Android UI as a layer on top of the 3D world, which can interact with the native platform library.

In this section:

Creating a UI

Native Android UI can be created on the Eegeo platform in the same way as a standard Android application; by using a markup file to specify the UI elements and layout. See Declaring Layout for an overview of how to design an Android UI. Layout XML files can be added to the standard resources directory of the Android application. The root layout file must contain an element with class com.eegeo.EegeoSurfaceView with id ‘surface’.

This surface should be positioned at the rear, and is the surface that the world will render into. Other than this requirement, the UI layout is flexible and can be structured to meet the application needs. An example of a root layout file is avalable in the SDK Examples, and an example of a trivial layout used by the PlaceJumpMenu Example is available also.

Loading a UI

UI can be loaded statically from markup, or injected dynamically from code. UI can be loaded statically via the R.layout construct, and added to the view hierarchy. To ensure the UI appears in front of the 3D world, the loaded UI view should be added to the ui_container view provided by the default root layout. This can be accomplished as follows:

UI can also be loaded programmatically. By doing so, views can be created, configured and added to the view hierarchy dynamically without a layout file. This can be accomplished as follows:

Java Event Handlers

In the previous example, a button was added programatically. This button can be programmatically wired up to handle click events in the standard way. This can be accomplished as follows:

Calling C++ Event Handlers From Java

When processing a UI event, it may be sufficient just to handle the event entirely in the Java application code. However, sometimes the application will want to query or manipulate the C++ platform API. To do so, we must use the Java Native Interface (JNI). The class which wishes to make a call to native code (i.e., the event handler or a dependency thereof) must declare a static method prefixed by ‘native’. The class should not implement this method, but should call it at the appropriate time. This can be accomplished as follows:

The application should include a C++ header which declares and exports a function signature that the JNI will match to the method declaration in the Java class. The Java class is com.mycompany.mypackage.MyClass. This name will be used to address the function from the native code. This can be accomplished as follows:

The application should also include a C++ implementation which defines the exported function. This function will be called when the native Java method is invoked. This can be accomplished as follows:

Calling Java methods from C++

p>It is possible to call Java methods from the C++ application code. Assume a Java class exists named ‘com.mycompany.myapp.Logger’ with a static void method ‘log’, taking a string parameter. To call this from C++, a reference to the class must first be obtained, then the method call can be made via the JNI. This can be accomplished as follows:

Android Concurrency Concerns

The eeGeo SDK utilises OpenGL for rendering. As per the Android Guidelines, the SDK OpenGL rendering occurs on a background thread. This introduces concurrency concerns that Application Developers must be aware of when interacting with the eeGeo SDK C++ types on Android

For Android Concurrency patterns and best practices please see the Concurrency Concerns on Android documentation.

For background information on the Android Guidelines with respect to threading and OpenGL applications, please see the GLSurfaceView documentation

Putting it all together: Example Application

Two examples in the Android SDK harness application demonstrate how Android native UI components can interact with the 3D World rendered by the Platform.

ShowJavaPlaceJumpUIExample

Demonstrates how Android UI components can be used to drive the behaviour of the Platform. This example displays a “Place Jump Menu” which allows the user to jump to particular locations around the world. Salient features in this example are that the C++ begins off the interactions, constructing a controller object via the JNI and passing the activity and a native pointer to this object. The object dyamically loads an XML layout, populates a menu, and calls back into the C++. The callback is parameterised on the native C++ object pointer, which can be used to call back on to the correct native object. Note that the native main c++ rendering loop runs in a separate thread from the Java UI; the Java must execute UI updates on the UI thread, using m_activity.runOnUiThread.

The key source files in this example are:

PositionJavaPinButtonExample

Shows how the Platform can drive the behaviour of Android UI components. In this example an Android UI Button is “tethered” to a particular Lat,Long location in the world. The C++ begins by creating a controller for containing the button, and caches the method to update the button location, which is called every render frame with updated data.

The key source files in this example are: