2 Mart 2016 Çarşamba

Android NDK Kullanımı

        Android Native Development Kit(NDK) bir android uygulamasında C ve C++ kodlarını kullanmamıza olanak sağlayan tool'ları barındırmaktadır.Bu C ve C++ kodlarını android uygulamamızda kullanabilmemiz için derleyerek dinamik veya statik kütüphanelere donüştürmemiz lazım.Bunun için NDK kullanırız.NDK kullanımına geçmeden önce NDK'nın kurulumunu  buradan  indirdikden sonra yapılabilir.Kurulum talimatları sayfada vardır.NDK yazdığımız C ve C++ kodlarını kütüphanelere dönüştürürken gnumake aracına ihtiyaç duymaktadır.Bunun için eğer kurulu değilse sisteminize Cygwin'i kurmanız  tavsiye  olunur.Bir örnek üzerinden giderek bu aracın kullanımına yakından bakalım.Bu yazıya geçmeden önce Java Native Interface yazısını okumanız  tavsiye olunur.

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

Hiç yorum yok:

Yorum Gönder