Android NDK Nedir?

Taha Cansızoğlu
HardwareAndro
Published in
5 min readJul 11, 2020

Android NDK, uygulamanızı C ve C ++ gibi dillerinde yazılmış kodlarınızı Native Android uygulamalarında kullanabilmemizi sağlayan bir araç setidir. Aynı şekilde bu diller için hazırlanmış olan kütüphaneleri de kullanmanıza yarıyor. Bunlar hem var olan hazır kütüphaneler hemde yüksek performans sağlayan API’ler olabilir(Vulkan,OpenGl…vb).

Niçin Kullanılır?

Kullanılmasındaki asıl amaç yüksek CPU gerektiren işlemlerdir. Çünkü C ve C++ gibi diller Java ve Kotlin gibi derlenirken JVM işleminden geçmiyor direk makina koduna çevriliyor ve bu bize Java/Kotlin gibi dillerden elde edemediğimiz bir hız veriyor. Özellikle oyun geliştiricileri gibi fazla performans elde etmek kişiler bu yola başvuruyor. Ayrıca C ve C++ kodumuzu farklı platformlar üzerinden de kullanabiliyoruz. Tabi bu o zaman bırakalım Kotlin’i, Java’yı C,C++ yazalım demek değil. Çünkü bir dili seçerken sadece o dilin performansına değil aynı zamanda dilin rahat kullanımına da bakarız. Gidip bir hesap makinesi uygulamasını Kotlin varken C yazmak bize ne kadar zaman kazandırır ki. En azından kendi adıma C/C++ ile Kotlin ve Javadan daha çok çalışan bir kişi olarak böyle bir uygulamada Kotlin daha ağır basıyor. Yani burada yapacağımız uygulamaya göre en uygun seçimi yapmalıyız.

Gel gelelim biz uygun seçimi yaptıkta nedir bu işi sağlayan şey diyorsanız sizlere JNI taktim edeyim.

JNI Nedir?

JNI yani Java Native Interface(Java Yerel Arayüzü) Java / Kotlin ve C / C++ kodu arasındaki arayüzdür. Android tarafından oluşturulan bayt kodunun native kodla iletişim kurması için JNI kullanılır. Tabi burada bizim C/C++ dan bildiğimiz veri türlerinin adı biraz farklı. Burada JNI’nin bizim için belirlediği tanımları kullanacağız.Tabi bu değerleri sadece fonksiyonun geri döndüreceği değeri ve parametrelerini tanımlarken kullanacağız fonksiyon içinde her şey bildiğiniz gibi. Onunda tablosu aşağıdaki gibi:

Evet, sadece önlerine j geliyor.

Örnek Kullanımlar

1.Hello World Uygulaması

İşin teorik kısımlarını elimden geldiğince sizlere anlattım. Birazda pratik kısmına geçersek size bir “Hello World” uygulaması ve yanına sadece “Hello World” yapmış demesinler diye birde ondan daha basit “Verilen sayının tam bölenlerini bulma” uygulaması yapacağım. :) Gönül sizlere daha iyi örnekler yapmak isterdi ama çok kısıtlı düzeyde Kotlin bilgim var. Bu yüzden bu iki örnekle olayı açıklamaya çalışacağım.

İlk olarak aşağıda gösterdiğim seçeneği seçerek Native C++ projemizi oluşturuyoruz.Tabi Sdk Managerdan Ndk’yı indirmeyi unutmayın.

Daha sonra karşınıza bildiğiniz MainActivity.kt çıkacak ve sol tarafta projenizin dosyaları olacak ama ekstra bir klasörle. O da cpp klasörü içinde ise C ++ kodlarımızı yazacağımız native-lib.cpp.

Şimdi native-lib.cpp dosyasına gidelim. Gördüğünüz gibi kütüphane eklemek C++ alıştığımız #include ile yapılıyor.

Aşağıda gördüğümüz kod parçası ise fonksiyonumuzun JNI tarafından derleneceği ve geri dönüş türünün jstring(String) olacağının tanımıdır.

extern “C” JNIEXPORT jstring JNICALL

Aşağıda ise fonksiyon tanımımızı yapıyoruz. Bu fonksiyon tanımını yaparken takip etmeniz gereken bir düzen var. O da bu Java_PackageName_ActivityName_MethodName şekildedir. Parametre olarak aldıkları ise JNI’nin içindeki fonksiyonlara erişmek için tanımlanan değişkenler. MainActivity içinde çağırırken bunları dahil bir daha yazmayacağız. Bunlar JNI’nin JVM istediği bir değişken ve bu işlemler arkaplanda yapılıyor. Altında C++’tan alışık olduğumuz hello adlı string değişkenine “Hello from C++” tanımlama. Biz bu kısmı “Hello World” olarak değiştireceğiz(Kütüphane tanımlamalarının altına using namespace std kullanarak stdden kurtulabilirsiniz). Return tarafında gördüğümüz kısım ise daha önce belirttiğim JNI’nin hazır bir fonksiyonlarından biri. Bu fonksiyon değiştirilmiş UTF-8 kodlamasındaki bir karakter dizisinden yeni bir java.lang.String nesnesi oluşturur. Bu fonksiyonların detaylarını buradan araştırabilirsiniz.

Yukarıda anlattıklarımız ile C++ tarafımdaki işimiz bitti. Şimdi işin Kotlin tarafına geçelim. Burada yapacağınız 2 iş var. İlk olarak 17. ve 22. satırlarda görüldüğü üzere kullanacağınız kütüphaneyi bildirmek daha sonra yukarı fonksiyon tanımını yapmak. Artık herhangi bir String’i stringFromJNI() fonksiyonunu çağırarak değerini “Hello World” yapabilirsiniz. Ben burada default olarak gelen textView’in textini fonksiyonumuzla eşitleyerek ekranda “Hello World” yazmasını sağlıyorum.

2. Tam Bölenleri Bulan Uygulama

Şimdi ise yukarıda anlattıklarım ile verilen sayının tam bölenlerini bulan uygulamayı açıklayacağım. Native-lib.cpp ven MainActivity.kt dosyalarım aşağıda görülüyor. Native-lib.cpp de hesapla adında bir fonksiyon oluşturdum ve sayi adında bir int değişkeni verdim. Bu değişken EditText’e girilen sayıya eşit olacak. Daha sonra basit bir döngü işlemi ile tam bölenlerin yazıldığı string sonuc_text’e döndürülecek ve işlemimiz bitecek.

Yaptığım uygulamanın ekran görüntüleri ise aşağıdaki gibidir.

Umarım sizlere bir şey anlatmayı, öğretmeyi başarmış ve herkesin hoşuna giden bir makale yazmışımdır. Buraya kadar gelip okuyan herkese çok teşekkür ederim.

Uygulamayı içeren GitHub reposu:

Ekstra teşekkür:

--

--