1 # Android tutorial 1: Link against GStreamer
7 This first Android tutorial is extremely simple: it just retrieves the
8 GStreamer version and displays it on the screen. It exemplifies how to
9 access GStreamer C code from Java and verifies that there have been no
12 ## Hello GStreamer \[Java code\]
14 The tutorial code is in the [gst-docs](https://cgit.freedesktop.org/gstreamer/gst-docs/) in the `tutorials/android-tutorial-1` subdirectory. This directories contains the usual Android NDK structure: a `src` folder for the Java code,
15 a `jni` folder for the C code and a `res` folder for UI resources.
17 We recommend that you open this project in Eclipse (as explained
18 in [](installing-for-android-development.md)) so you can
19 easily see how all the pieces fit together.
21 Let’s first introduce the Java code, then the C code and finally the
22 makefile that allows GStreamer integration.
24 **src/org/freedesktop/gstreamer/tutorials/tutorial_1/Tutorial1.java**
27 package org.freedesktop.gstreamer.tutorials.tutorial_1;
29 import android.app.Activity;
30 import android.os.Bundle;
31 import android.widget.TextView;
32 import android.widget.Toast;
34 import org.freedesktop.gstreamer.GStreamer;
36 public class Tutorial1 extends Activity {
37 private native String nativeGetGStreamerInfo();
39 // Called when the activity is first created.
41 public void onCreate(Bundle savedInstanceState)
43 super.onCreate(savedInstanceState);
47 } catch (Exception e) {
48 Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
53 setContentView(R.layout.main);
55 TextView tv = (TextView)findViewById(R.id.textview_info);
56 tv.setText("Welcome to " + nativeGetGStreamerInfo() + " !");
60 System.loadLibrary("gstreamer_android");
61 System.loadLibrary("tutorial-1");
67 Calls from Java to C happen through native methods, like the one
71 private native String nativeGetGStreamerInfo();
74 This tells Java that there exists a method with this signature somewhere
75 so it compiles happily. It is your responsibility to ensure that, **at
76 runtime**, this method is accessible. This is accomplished by the C code
79 The first bit of code that gets actually executed is the static
80 initializer of the class:
84 System.loadLibrary("gstreamer_android");
85 System.loadLibrary("tutorial-1");
89 It loads `libgstreamer_android.so`, which contains all GStreamer
90 methods, and `libtutorial-1.so`, which contains the C part of this
91 tutorial, explained below.
93 Upon loading, each of these libraries’ `JNI_OnLoad()` method is
94 executed. It basically registers the native methods that these libraries
95 expose. The GStreamer library only exposes a `init()` method, which
96 initializes GStreamer and registers all plugins (The tutorial library is
97 explained later below).
101 GStreamer.init(this);
102 } catch (Exception e) {
103 Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
109 Next, in the `OnCreate()` method of the
110 [Activity](http://developer.android.com/reference/android/app/Activity.html)
111 we actually initialize GStreamer by calling `GStreamer.init()`. This
113 [Context](http://developer.android.com/reference/android/content/Context.html)
114 so it cannot be called from the static initializer, but there is no
115 danger in calling it multiple times, as all but the first time the calls
118 Should initialization fail, the `init()` method would throw an
119 [Exception](http://developer.android.com/reference/java/lang/Exception.html)
120 with the details provided by the GStreamer library.
123 TextView tv = (TextView)findViewById(R.id.textview_info);
124 tv.setText("Welcome to " + nativeGetGStreamerInfo() + " !");
127 Then, the native method `nativeGetGStreamerInfo()` is called and a
128 string is retrieved, which is used to format the content of the
129 [TextView](http://developer.android.com/reference/android/widget/TextView.html)
132 This finishes the UI part of this tutorial. Let’s take a look at the C
135 ## Hello GStreamer \[C code\]
142 #include <android/log.h>
148 static jstring gst_native_get_gstreamer_info (JNIEnv* env, jobject thiz) {
149 char *version_utf8 = gst_version_string();
150 jstring *version_jstring = (*env)->NewStringUTF(env, version_utf8);
151 g_free (version_utf8);
152 return version_jstring;
155 static JNINativeMethod native_methods[] = {
156 { "nativeGetGStreamerInfo", "()Ljava/lang/String;", (void *) gst_native_get_gstreamer_info}
159 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
162 if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
163 __android_log_print (ANDROID_LOG_ERROR, "tutorial-1", "Could not retrieve JNIEnv");
166 jclass klass = (*env)->FindClass (env, "org/freedesktop/gstreamer/tutorials/tutorial_1/Tutorial1");
167 (*env)->RegisterNatives (env, klass, native_methods, G_N_ELEMENTS(native_methods));
169 return JNI_VERSION_1_4;
173 The `JNI_OnLoad()` method is executed every time the Java Virtual
174 Machine (VM) loads a library.
176 Here, we retrieve the JNI environment needed to make calls that interact
182 if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
183 __android_log_print (ANDROID_LOG_ERROR, "tutorial-1", "Could not retrieve JNIEnv");
188 And then locate the class containing the UI part of this tutorial using
193 jclass klass = (*env)->FindClass (env, "org/freedesktop/gstreamer/tutorials/tutorial_1/Tutorial1");
196 Finally, we register our native methods with `RegisterNatives()`, this
197 is, we provide the code for the methods we advertised in Java using the
202 (*env)->RegisterNatives (env, klass, native_methods, G_N_ELEMENTS(native_methods));
205 The `native_methods` array describes each one of the methods to register
206 (only one in this tutorial). For each method, it provides its Java
208 signature](http://docs.oracle.com/javase/1.5.0/docs/guide/jni/spec/types.html#wp276)
209 and a pointer to the C function implementing it:
212 static JNINativeMethod native_methods[] = {
213 { "nativeGetGStreamerInfo", "()Ljava/lang/String;", (void *) gst_native_get_gstreamer_info}
217 The only native method used in this tutorial
218 is `nativeGetGStreamerInfo()`:
221 jstring gst_native_get_gstreamer_info (JNIEnv* env, jobject thiz) {
222 char *version_utf8 = gst_version_string();
223 jstring *version_jstring = (*env)->NewStringUTF(env, version_utf8);
224 g_free (version_utf8);
225 return version_jstring;
229 It simply calls `gst_version_string()` to obtain a string describing
230 this version of GStreamer. This [Modified
231 UTF8](http://en.wikipedia.org/wiki/UTF-8#Modified_UTF-8) string is then
232 converted to [UTF16](http://en.wikipedia.org/wiki/UTF-16) by `
233 NewStringUTF()` as required by Java and returned. Java will be
234 responsible for freeing the memory used by the new UTF16 String, but we
235 must free the `char *` returned by `gst_version_string()`.
237 ## Hello GStreamer \[Android.mk\]
242 LOCAL_PATH := $(call my-dir)
244 include $(CLEAR_VARS)
246 LOCAL_MODULE := tutorial-1
247 LOCAL_SRC_FILES := tutorial-1.c
248 LOCAL_SHARED_LIBRARIES := gstreamer_android
249 LOCAL_LDLIBS := -llog
250 include $(BUILD_SHARED_LIBRARY)
252 ifndef GSTREAMER_ROOT
253 ifndef GSTREAMER_ROOT_ANDROID
254 $(error GSTREAMER_ROOT_ANDROID is not defined!)
256 GSTREAMER_ROOT := $(GSTREAMER_ROOT_ANDROID)
258 GSTREAMER_NDK_BUILD_PATH := $(GSTREAMER_ROOT)/share/gst-android/ndk-build/
259 GSTREAMER_PLUGINS := coreelements
260 include $(GSTREAMER_NDK_BUILD_PATH)/gstreamer-1.0.mk
263 This is a barebones makefile for a project with GStreamer support. It
264 simply states that it depends on the `libgstreamer_android.so` library
265 (line 7), and requires the `coreelements` plugin (line 18). More complex
266 applications will probably add more libraries and plugins
271 This ends the first Android tutorial. It has shown that, besides the
272 interconnection between Java and C (which abides to the standard JNI
273 procedure), adding GStreamer support to an Android application is not
274 any more complicated than adding it to a desktop application.
276 The following tutorials detail the few places in which care has to be
277 taken when developing specifically for the Android platform.
279 As usual, it has been a pleasure having you here, and see you soon\!
281 [screenshot]: images/tutorial-android-link-against-gstreamer-screenshot.png