NDK - Native Development Kit NDK je sada nástrojov, ktorá umožňuje implementovať natívny kód v iných jazykoch (C, C + +). NDK využíva štandardný java framework k tomu určený – JNI.
JNI – Java Native Interface je framework umožňujúci volať natívne programy a knižnice napísané v iných jazykoch (C, C++, ..) priamo v kóde, bežiacom v Java Virtual Machine (JVM).
Uplatnenie:
- využitie staršieho kódu napísaného v inom jazyku (nie Java) bez nutnosti ho prepisovať do javy
- využitie API iných jazykov (nie Java)
- komunikácia s HW
Obmedzenia (nevýhody):
- strata platformovej nezávislosti javy (natívny kód je potrebne prepísať pre každú platformu)
- vlastnosti javy ako typová bezpečnosť, garbage collector sa nevzťahujú na natívny kód
Implementácia:
- triede v ktorej chceme volať metódu, implementovanú v natívnom jazyku, vytvoríme deklaráciu natívnej metódy. Natívna metóda musí obsahovať modifikátor „native“,
public native int callJni(int i);
- Signatúru natívnej metódy môžeme vytvoriť pomocou nástroja „javah“ (javah -jni ClassName), alebo ju vytvoríme ručne, teda vytvoríme samostatný súbor pre požadovanú metódu (napr.: „jni_part.cpp“) v adresári „jni“ (napr.: project_folder/jni/jni_part.cpp),
#include <jni.h> extern "C" { JNIEXPORT jint JNICALL Java_com_example_test04jni_MainActivity_callJni(JNIEnv*, jclass, jint); JNIEXPORT jint JNICALL Java_com_example_test04jni_MainActivity_callJni(JNIEnv* je, jclass jc, jint i) { return (i * i); } }
- V mieste umiestnenia natívnej funkcie vytvoríme „makefile“ s názvom „Android.mk“ pre android build,
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := jni_example LOCAL_SRC_FILES := jni_part.cpp include $(BUILD_SHARED_LIBRARY)
- Zbuildujeme natívnu metódu pomocou „android-ndk“,
LINUX shell: "project dir"$ ~/.android-ndk-r8c/ndk-build
- Nakoniec v android aplikácii v mieste volania natívnej metódy, najskôr načítame knižnicu, ktorá bude kompilovať natívnu metódu a zavoláme samotnú metódu.
// Load native library System.loadLibrary("jni_example"); ... // call native method: "callJni(i)" textView_result.setText(Integer.toString(callJni(i)));
Zdroj android triedy, v ktorej bola volaná natívna metóda:
package com.example.test04jni; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity { private TextView textView_result; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Load native library System.loadLibrary("jni_example"); textView_result = (TextView) findViewById(R.id.textView_result); final Button btn_start = (Button) findViewById(R.id.button1); btn_start.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Integer i = 10; // call native method: "callJni(i)" textView_result.setText(Integer.toString(callJni(i))); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } // Declaration of native methods. public native int callJni(int i); }
Zdroj príkladu: Android-NDK-JNI-example