HelloNDK adında bir Android uygulamamız olsun ve bu uygulamanın Ana activitesinden bir native method çağıralım.
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package com.example.hellondk; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { public native String getString(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } } |
Görüldüyü gibi getString() adında bir native method tanımladık ama henüz çağırılmasına dair herhangi bir kod satırı yazmadık çünkü önce bu metodu içinde barındıran bir header(.h) dosyası oluşturup bu metodun implementasyonunu gerçekleştirmemiz lazım.(Not:method tanımlandığına göre herhangi bir yerden çağrılabilir fakat methoda ait kütüphane henüz olmadığı için runtime anında hata oluşacaktır)
Header dosyamızı olşuturmak için;
1 2 | >mkdir jni && cd jni >javah -classpath "<proje_yolu>/bin/classes/;<sdk>/platforms/android-xx/android.jar" -o main.h <paket_yolu>.MainActivity |
(Not:Bu durumda paket_yolu'muz "com.example.hellondk"dir.)
main.h
1 2 3 4 5 6 7 | /* * Class: com_example_hellondk_MainActivity * Method: getString * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_example_hellondk_MainActivity_getString (JNIEnv *, jobject); |
Aynı dizinde main.c dosyası oluşturarak getString metodunun implementasyonunu yapalım.
main.c
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <main.h> #include <jni.h> JNIEXPORT jstring JNICALL Java_com_example_hellondk_MainActivity_getString(JNIEnv *env, jobject obj){ return (*env)->NewStringUTF(env, "Hello from native code!!!"); } JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *javaVm, void *reserved) { return JNI_VERSION_1_6; } |
Buradaki JNI_OnLoad metodu android işletim sistemine jni hakkındaki version bilgisini döndürmektedir.Bu metod kullanılmadığı takdirde hata oluşabilir.Şimdi ise yazdığımız getString metodunu derleyerek androidin kullanabileceği bir kütüphaneye dönüştürelim. Android NDK yı kullanacağımız yer burasıdır.main.c kod dosyamızı derlemek için ndk iki makefile dosyasına ihtiyaç duymaktadır.
1.Android.mk
1 2 3 4 5 6 7 8 | LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := myjni LOCAL_SRC_FILES := main.c include $(BUILD_SHARED_LIBRARY) |
Bu makefile dosyasında ndk'ın derleyeceği native kod hakkındaki parametreleri tanımlanmaktadır. LOCAL_SRC_FILES parametresi derlenecek native kod dosyalarını LOCAL_MODULE ise oluşturulacak olan kütüphanenin adını tanımlar.
2.Applicaiton.mk
1 | APP_ABI := all |
Bu makefile dosyasında ise oluşturulacak olan kütüphanenin hangi platform veya mimariye spesifik olacağını tanımlayan parametreler tanımlanmaktadır.Şuan için gereken tek parametre uygulamanın kullanılacağı android mimarilerini tanımlayan APP_ABI parametresidir.Bu iki makefile dosyasını projemizin jni klasörüne kaydetdikden sonra ndk'ın ndk-build scriptini çalıştırmamız lazım . Projemizin kök dizinine giderek aşağıdaki komutu çalıştırırsak bizim için gereken native kütüphanemiz oluşturulacakdır.
1 | ndk-build |
Bu komut çalıştırıldıkdan sonra projemizin libs kalsörü altında oluşturulan kütüphanenin her mimariye göre bir örneğinin oluşturulduğunu görebiliriz.Bu kütüphaneyi,dolayısıyla native metodumuzu kullanmak için MainActivity'mizi aşağıdaki şekilde değişirsek;
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package com.example.hellondk; import android.app.Activity; import android.os.Bundle; import android.widget.Toast; public class MainActivity extends Activity { static{ System.loadLibrary("myjni"); } public native String getString(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toast.makeText(getApplicationContext(), getString(), Toast.LENGTH_LONG).show(); } } |
ve uygulamamızı çalıştırırsak aşağıdaki gibi bir sonuç elde ederiz.
[1]http://developer.android.com/ndk/guides/index.html