Android - How is threading implemented in the samples?

August 10, 2012 - 2:49pm #1
Android native methods

 

In the Android samples, most native methods can be divided into two categories: those called from the main thread and those called from the GL thread. In ImageTargets.cpp, any method that starts with Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer is called from the GL thread. These methods are called from the onSurfaceCreated, onSurfaceChanged, or onDrawFrame callback methods in ImageTargetsRenderer.java, which are called by Android on a separate OpenGL thread. Most of the methods that start with Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargets are called from the main thread. One exception is the loadTrackerData method, which is called from an AsyncTask in ImageTargets.java.

 

OpenGL methods

 

On Android, OpenGL methods should only be called from the GL thread. This is why, for instance, the samples create textures in two steps, first copying the info from Java on the main thread (initApplicationNative) and then generating the textures on the GL thread (initRendering). The iOS samples divide the work a little differently. All OpenGL setup (creating textures, loading models, etc.) happens on the main thread. Then a background thread is used to call renderFrameQCAR each frame. This means that two separate threads are modifying the same OpenGL context, which is only safe when you can guarantee that the two threads will not modify it simultaneously.

 

Changing the UI

 

In the samples, tracking events are handled on the GL thread by the renderFrame method (renderFrameQCAR on iOS). This is where we typically query which trackables are active and use their pose to render 3D content on top. On both Android and iOS, methods that modify the UI should only be called on the main thread. So if you want to modify the UI in response to a tracking event (e.g. a target being found) you'll need to communicate across threads. There are several ways to do this in Android, see the "Painless Threading" article in the Android documentation: http://developer.android.com/resources/articles/painless-threading.html For some sample code that uses Handlers to send a message to the main thread see this article: AndroidUIChanges.xml On iOS, you can use the NSObject performSelectorOnMainThread method:

[self performSelectorOnMainThread:@selector(methodName) withObject:nil];

 

QCAR UpdateCallback

The QCAR_onUpdate method is called by Vuforia when new tracking data is available (see the QCAR::UpdateCallback class and the QCAR::registerCallback method). On Android, this is typically called on the main thread. On iOS, it is typically called on a background thread. It is safest to assume this method is not called on the main thread and use thread-safe procedures accordingly.

 

Topic locked