{"id":1014,"date":"2017-06-27T22:55:31","date_gmt":"2017-06-27T20:55:31","guid":{"rendered":"http:\/\/metehantoksoy.com\/?p=1014"},"modified":"2017-06-27T22:55:31","modified_gmt":"2017-06-27T20:55:31","slug":"android-hello-jni","status":"publish","type":"post","link":"https:\/\/metehantoksoy.com\/?p=1014","title":{"rendered":"Android &#8211; Hello JNI"},"content":{"rendered":"<p>Merhaba arkada\u015flar. Uzun bir aradan sonra tekrar blog yazmaya ba\u015fl\u0131yorum. Bu yaz\u0131da e-posta\u00a0ile gelen sorular \u00fczerine biraz JNI \u00fczerinde duraca\u011f\u0131z. Bu yaz\u0131 giri\u015f niteli\u011finde olup JNI ile ileri d\u00fczeye sonraki yaz\u0131larda ge\u00e7ece\u011fiz.<\/p>\n<h2><strong>JNI Nedir?<\/strong><\/h2>\n<p>JNI (<em><strong>Java Native Interface<\/strong><\/em>), native kodlarla (<em><strong>C, C++<\/strong><\/em>) java kodlar\u0131n\u0131n konu\u015fabilmesi i\u00e7in geli\u015ftirilmi\u015f bir aray\u00fczd\u00fcr. JNI ile ilk cal\u0131\u015fmaya ba\u015flad\u0131\u011f\u0131mda kafamda bir kar\u0131\u015f\u0131kl\u0131k olu\u015fmu\u015ftu. Sizde de olu\u015fmamas\u0131 i\u00e7in buraya not d\u00fc\u015f\u00fcyorum:<\/p>\n<blockquote><p>Android platformunun native dili Java&#8217;d\u0131r. Fakat native kod diye bahsetti\u011fimiz kodlar Java de\u011fil JNI kodlar\u0131d\u0131r. Bu ikisi farkl\u0131 ba\u011flamlarda ge\u00e7erlidir. Bu yaz\u0131 boyunca native diye bahsetti\u011fimiz kodlar Java de\u011fil C ve C++ dilleridir.<\/p><\/blockquote>\n<p><!--more--><\/p>\n<h2>JNI Temelde Nas\u0131l \u00c7al\u0131\u015f\u0131r?<\/h2>\n<p>JNI asl\u0131nda Android&#8217;in bir \u00f6zelli\u011fi de\u011fildir. Java ile birlikte Android gelen ve Android i\u00e7in sadece C veya C++ dilleriyle yaz\u0131lan kodlard\u0131r. Yaz\u0131lan bu kodlar\u00a0<em><strong>Android NDK build<\/strong><\/em> ile derlenerek <em><strong>shared object library(.so)<\/strong><\/em>&#8216;ler olu\u015fur. Bu shared object\u00a0library&#8217;ler cihazlarda \u00e7al\u0131\u015fmaya uygun binary kodlar ve derleme flaglerine g\u00f6re de sembolleri i\u00e7erir. Bu k\u00fct\u00fcphaneler \u00e7al\u0131\u015fma an\u0131nda Android sanal makinesi contexti (<em>Dalwik veya ART<\/em>) i\u00e7erisine y\u00fcklenir. Bir Android uygulamas\u0131nda bulunan her kod sanal makine contextinde \u00e7al\u0131\u015ft\u0131r\u0131l\u0131r ve bu native kodlar\u0131 sanal makine contextinde \u00e7al\u0131\u015ft\u0131rabilmek JNI kullan\u0131r\u0131z. JNI ve JNI implementasyonu Android i\u00e7erisinde g\u00f6m\u00fcl\u00fc olarak gelir ve native geli\u015ftiriciler olarak bu implementasyona ula\u015fabilmemiz bir header dosyas\u0131 vard\u0131r.<\/p>\n<p>Android taraf\u0131ndan native k\u00fct\u00fcphanemizi load etti\u011fimizde, bunun i\u00e7in <strong><em>System.loadLibrary()<\/em><\/strong> methodunu kullanabiliriz, native implementasyonumuzda <em><strong>JNI_OnLoad()<\/strong><\/em> methodunu yazm\u0131\u015fsak bu method tetiklenir. Ard\u0131ndan Java\u00a0ile yazd\u0131\u011f\u0131m\u0131z methodlar, Android taraf\u0131nda native olarak tan\u0131mlad\u0131\u011f\u0131m\u0131z methodlar ile maplenir.<\/p>\n<p>Android taraf\u0131ndan bir native methodu \u00e7a\u011f\u0131rd\u0131m\u0131zda Java kodlar\u0131n\u0131n \u00e7al\u0131\u015fmas\u0131 o thread i\u00e7in durdurulur ve native kodlar \u00e7al\u0131\u015ft\u0131r\u0131lmaya ba\u015flan\u0131r. Native kodlar\u0131n \u00e7al\u0131\u015fmas\u0131 bitti\u011finde ki bu ko\u015fula bir de\u011fer d\u00f6nd\u00fcrmesi de dahildir Java kodlar\u0131n\u0131n \u00e7al\u0131\u015fmas\u0131 devam eder.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1028\" src=\"https:\/\/metehantoksoy.com\/wp-content\/uploads\/2017\/04\/jnifigure1.gif\" alt=\"JNIFigure1.gif\" width=\"1173\" height=\"1038\" \/><\/p>\n<h2>Neden JNI Kullanmaya Ihtiya\u00e7 Duyar\u0131z?<\/h2>\n<p>JNI&#8217;in kullan\u0131lma ama\u00e7lar\u0131 temelde \u015f\u00f6yle s\u0131ralayabiliriz:<\/p>\n<ul>\n<li>En ge\u00e7erli sebep olarak performans<a href=\"https:\/\/developer.android.com\/training\/articles\/perf-jni.html\">\u00b9<\/a>. C, C++ ile yaz\u0131lan kodlar \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131ndan dolay\u0131 donan\u0131m seviyesine Java&#8217;dan daha yak\u0131nd\u0131r. Fakat native kodlar da Dalvik i\u00e7erisinde \u00e7al\u0131\u015ft\u0131r\u0131ld\u0131\u011f\u0131n\u0131 unutmamak gerekir. Buna ra\u011fmen yine de h\u0131zl\u0131d\u0131r diyebiliriz.<\/li>\n<li>Hali haz\u0131rda C, C++ ile implemente edilmi\u015f bir k\u00fct\u00fcphanenizi kullanabilmek i\u00e7in.<\/li>\n<li>Baz\u0131 durumlar i\u00e7in Android kodlar\u0131na g\u00f6re daha fazla gizlilik sa\u011flayabilir.<\/li>\n<\/ul>\n<p>Fakat unutulmamas\u0131 gereken \u00f6nemli noktalardan biri native k\u00fct\u00fcphaneler makine kodlar\u0131ndan olu\u015ftu\u011fu i\u00e7in uyumluluk a\u00e7\u0131s\u0131ndan \u00e7al\u0131\u015ft\u0131r\u0131lmak istenen her i\u015flemci mimarisi i\u00e7in (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Application_binary_interface\" target=\"_blank\" rel=\"noopener\">ABI<\/a>) derlenmesi gerekir ve bu da uygulama boyutunun artmas\u0131na yol a\u00e7acakt\u0131r. Bir di\u011feri ise <em>Java-native<\/em> ve <em>native-Java<\/em> \u00e7a\u011fr\u0131lar\u0131n\u0131n ve ge\u00e7i\u015flerinin bir maliyetinin olmas\u0131. Yani JN\u0130 \u00e7a\u011fr\u0131lar\u0131n\u0131n say\u0131s\u0131 art\u0131k\u00e7a performans konusunda kay\u0131pa da yol a\u00e7abilir<a href=\"https:\/\/developer.android.com\/training\/articles\/perf-tips.html#NativeMethods\" target=\"_blank\" rel=\"noopener\">\u00b2<\/a>.<\/p>\n<h2><strong>Merhaba JNI<\/strong><\/h2>\n<p>JNI&#8217;i ve \u00e7al\u0131\u015fma mant\u0131\u011f\u0131n\u0131n temelini \u00f6zetledikten sonra Android ile JNI kullanarak native kodlar i\u00e7eren &#8220;<em><strong>Hello JNI<\/strong><\/em>&#8221; uygulamam\u0131za ge\u00e7ebiliriz. Projenin kaynak kodlar\u0131na <a href=\"https:\/\/github.com\/birfincankafein\/metehantoksoy.com\">GitHub<\/a>&#8216;dan\u00a0ula\u015fabilirsiniz.<\/p>\n<p>Bir Android uygulamas\u0131na native kodlar i\u00e7in iki konum bulunur.<\/p>\n<p>Bu konumlardan ilki native kaynak kodlar\u0131 bulundurdu\u011fumuz &#8220;<em><strong>jni<\/strong><\/em>&#8221; klas\u00f6r\u00fcd\u00fcr. Bu klas\u00f6r\u00fcn alt\u0131nda Android uygulamam\u0131zla birlikte geli\u015ftirdi\u011fimiz C, C++ kodlar\u0131 bulunur.<\/p>\n<p>Di\u011fer bir konum ise &#8220;<em><strong>jniLibs\/CPU_ABI<\/strong><\/em>&#8221; klas\u00f6r\u00fcd\u00fcr. Bu klas\u00f6r alt\u0131nda ise daha \u00f6nceden derlenen shared object library (.so) k\u00fct\u00fcphaneleri bulunur. Bu native k\u00fct\u00fcphaneler, &#8220;<em><strong>jniLibs<\/strong>&#8221;\u00a0<\/em>klas\u00f6r\u00fc alt\u0131nda derlendikleri ABI yap\u0131lar\u0131na yani \u00f6zetle i\u015flemci mimarilerine g\u00f6re klas\u00f6rlerin i\u00e7inde bulunmal\u0131d\u0131rlar. Android taraf\u0131ndan desteklenen i\u015flemci mimarileri\u00a0<a href=\"https:\/\/developer.android.com\/ndk\/guides\/abis.html\" target=\"_blank\" rel=\"noopener\">Developer Android<\/a>&#8216;de belirtildi\u011fi gibi a\u015fa\u011f\u0131daki gibidir:<\/p>\n<table border=\"0\" rules=\"NONE\" cellspacing=\"0\">\n<colgroup>\n<col width=\"101\" \/>\n<col width=\"101\" \/><\/colgroup>\n<tbody>\n<tr>\n<td style=\"text-align:center;\" align=\"LEFT\" width=\"101\" height=\"19\"><strong>ABI<\/strong><\/td>\n<td style=\"text-align:center;\" align=\"LEFT\" width=\"101\"><strong>Konum<\/strong><\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" height=\"19\">armeabi<\/td>\n<td align=\"LEFT\">jniLibs\/armeabi<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" height=\"19\">armeabi-v7a<\/td>\n<td align=\"LEFT\">jniLibs\/armeabi-v7a<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" height=\"19\">arm64-v8a<\/td>\n<td align=\"LEFT\">jniLibs\/arm64-v8a<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" height=\"19\">x86<\/td>\n<td align=\"LEFT\">jniLibs\/x86<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" height=\"19\">x86_64<\/td>\n<td align=\"LEFT\">jniLibs\/x86_64<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" height=\"19\">mips<\/td>\n<td align=\"LEFT\">jniLibs\/mips<\/td>\n<\/tr>\n<tr>\n<td align=\"LEFT\" height=\"19\">mips64<\/td>\n<td align=\"LEFT\">jniLibs\/mips64<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Kulland\u0131\u011f\u0131m\u0131z <em><strong>.so<\/strong><\/em> k\u00fct\u00fcphaneleri i\u00e7in durum b\u00f6yle iken kodlar\u0131n\u0131 <em><strong>jni<\/strong> <\/em>klas\u00f6r\u00fc alt\u0131nda tuttu\u011fumuz native k\u00fct\u00fcphanelerimiz i\u00e7in ayarlamay\u0131 gradle \u00fczerinden yapabiliriz. Gradle ile <em><strong>NDK Build<\/strong><\/em> kullanarak build ald\u0131\u011f\u0131m\u0131z bu native k\u00fct\u00fcphaneler tek bir .so dosyas\u0131nda birle\u015ftirilecektir. Gradle ile <em><strong>NDK Build<\/strong><\/em> ederken mod\u00fcl\u00fcn\u00fcz\u00fcn <em><strong>build.gradle\u00a0<\/strong><\/em>dosyas\u0131na a\u015fa\u011f\u0131daki kodlar\u0131 eklemeniz yeterli olacakt\u0131r.<\/p>\n<p><span style=\"font-family:Consolas, Monaco, monospace;\">ndk {<\/span><\/p>\n<pre>    moduleName \"hello-jni\"\n    stl \"gnustl_shared\"\n    abiFilters 'armeabi', 'armeabi-v7a', 'x86'\n}<\/pre>\n<p>Burada dikkat etmeniz gereken bir nokta mevcut. E\u011fer <em><strong>jniLibs<\/strong> <\/em>alt\u0131na ekledi\u011finiz nat\u0131ve k\u00fct\u00fcphane <em>armeabi<\/em> destekliyorsa ve siz <em>armeabi-v7a<\/em> ile kendi k\u00fct\u00fcphanenizi build ald\u0131ysan\u0131z bu durumda <em>armeabi-v7a<\/em> destekleyen cihazlarda harici <em><strong>native k\u00fct\u00fcphanenizi kullanamayacas\u0131n\u0131z<\/strong><\/em> \u00e7\u00fcnk\u00fc bu cihaz sadece <em>armeabi-v7a<\/em> klas\u00f6r\u00fcne bakacakt\u0131r, ayn\u0131 zamanda ekledi\u011finiz harici nat\u0131ve k\u00fct\u00fcphane <em>armeabi-v7a<\/em> destekliyor ve siz kendi k\u00fct\u00fcphanenizi <em>armeabi<\/em> ile build ad\u0131ysan\u0131z bu defa da kendi k\u00fct\u00fcphanenizi kullanamayacaks\u0131n\u0131z ve uygulaman\u0131z her iki durumda da nat\u0131ve k\u00fct\u00fcphaneyi y\u00fcklerken <strong>UnsatisfiedLinkError<\/strong> hatas\u0131n\u0131 alacaks\u0131n\u0131z. Yani \u00f6zetle harici k\u00fct\u00fcphaneniz varsa veya kulland\u0131\u011f\u0131n\u0131z bir k\u00fct\u00fcphane kendi i\u00e7erisinde native k\u00fct\u00fcphane bar\u0131nd\u0131r\u0131yor ve siz bunlardan farkl\u0131 mimaride kendi k\u00fct\u00fcphanenizi build al\u0131rsan\u0131z <em><strong>uygulaman\u0131z \u00e7al\u0131\u015fmayacakt\u0131r<\/strong><\/em>.<\/p>\n<p>Bu bilgilerden sonra \u00f6rnek uygulamam\u0131za ge\u00e7ebiliriz. \u00d6rnek uygulamam\u0131z\u0131 3 a\u015famada olu\u015fturabiliriz.<\/p>\n<h3>1. Native K\u00fct\u00fcphane Klas\u00f6rleri<\/h3>\n<p>\u00d6rnek uygulamam\u0131z\u0131 Android Studio&#8217;nun varsay\u0131lan mod\u00fcl\u00fc olan &#8216;app&#8217; ile geli\u015ftiriyoruz. &#8220;<em><strong>app\/main\/<\/strong><\/em>&#8221; dizini alt\u0131na <em><strong>jni<\/strong><\/em>\u00a0dizinini olu\u015fturuyoruz ve i\u00e7ine &#8216;hello-jni.cpp&#8217; dosyas\u0131n\u0131 olu\u015fturuyoruz.<\/p>\n<h3>2. Kodlama<\/h3>\n<h4>2.1. Android\u00a0Java Kodlari<\/h4>\n<p>Uygulama a\u00e7\u0131l\u0131\u015f\u0131nda kendi yazd\u0131\u011f\u0131m\u0131z native k\u00fct\u00fcphanemizin y\u00fcklenmesi i\u00e7in &#8220;<em><strong>build.gradle<\/strong><\/em>&#8221; dosyas\u0131na yazd\u0131\u011f\u0131m\u0131z ndk mod\u00fcl ad\u0131yla olu\u015fan k\u00fct\u00fcphanemizi y\u00fckleyelim.<\/p>\n<pre>static{\n    \/\/ Loading static library\n    System.loadLibrary(\"hello-jni\");\n}<\/pre>\n<p>Java taraf\u0131ndan native tarafta \u00e7a\u011f\u0131raca\u011f\u0131m\u0131z metodu belirtelim. Bu metodu normal java metodu \u00e7a\u011f\u0131r\u0131yormu\u015f gibi &#8220;<em><strong>addAndLongToastNumbers(100, 75)<\/strong><\/em>&#8221; gibi \u00e7a\u011f\u0131rabiliriz. Bu \u00e7a\u011f\u0131rada JNI araya girerek native tarafta implemente etti\u011fimiz bu kodu \u00e7al\u0131\u015ft\u0131racakt\u0131r.<\/p>\n<pre>private native void addAndLongToastNumbers(int number1, int number2);<\/pre>\n<p>Native taraftan Java taraf\u0131nda \u00e7a\u011f\u0131raca\u011f\u0131m\u0131z metodumuzu yazal\u0131m.<\/p>\n<blockquote><p>Native taraftan \u00e7a\u011f\u0131rmak i\u00e7in Java taraf\u0131na implemente etti\u011finiz methodlar\u0131n sonuna, kodunuzun okunabilirli\u011fini art\u0131rmak i\u00e7in &#8220;<em><strong>__N<\/strong><\/em>&#8221; ekini ekleyebilirsiniz.<\/p><\/blockquote>\n<pre>\/\/ __N tag is for understanding this method will be called from native side.\nprivate void makeToastLong__N(int result){\n    Toast.makeText(this, \"Native Long Result is: \" + result, Toast.LENGTH_LONG).show();\n}<\/pre>\n<h4>2.1. Native Kodlar<\/h4>\n<p>Olu\u015fturdu\u011fumuz &#8220;<em><strong>hello-jni.cpp<\/strong><\/em>&#8221;\u00a0dosyas\u0131n\u0131n i\u00e7ine test kodlar\u0131m\u0131z\u0131, JNI&#8217;a \u00f6zel de\u011fi\u015fkenleri ve methodlar\u0131 kullanabilmek header dosyas\u0131n\u0131 ekleyelim.<\/p>\n<p><span style=\"font-family:Consolas, Monaco, monospace;\">#include &lt;jni.h&gt;<\/span><\/p>\n<p>Java taraf\u0131ndan native tarafta implemente etti\u011fimiz kodu \u00e7a\u011f\u0131rmak i\u00e7in sadece tan\u0131mlamak yeterken native taraftan Java taraf\u0131na implemente etti\u011fimiz metodu \u00e7a\u011f\u0131rmak i\u00e7in:<\/p>\n<ul>\n<li>\u00d6nce methodun implemente edildi\u011fi class&#8217;\u0131n referans\u0131n\u0131 JNI methodlar\u0131 ile bulal\u0131m.<\/li>\n<li>\n<pre>\/\/ We should find class before calling its method\njclass clazz = env-&gt;FindClass(\"com\/birfincankafein\/hellojni\/MainActivity\");<\/pre>\n<\/li>\n<li>Class \u00fczerinden \u00e7a\u011f\u0131rmak istedi\u011fimiz metodun referans\u0131n\u0131 method ad\u0131, parametre ve geri d\u00f6n\u00fc\u015f tipi ile bulal\u0131m.<\/li>\n<li>\n<pre>\/\/ (I)V means accepts int parameters and returns void\njmethodID method = env-&gt;GetMethodID(clazz,\"makeToastLong__N\",\"(I)V\");<\/pre>\n<\/li>\n<\/ul>\n<p>Metodu bulmak i\u00e7in JNI&#8217;in &#8220;<em><strong>GetMethodID<\/strong><\/em>&#8221; fonksiyonunu kullanaca\u011f\u0131z. Bu metodun ilk parametresi metodun tan\u0131ml\u0131 oldu\u011fu class&#8217;\u0131n referans\u0131, ikinci parametresi metod ad\u0131, \u00fc\u00e7\u00fcnc\u00fc parametre ise JNI formatl\u0131 method imzas\u0131. Bu metod imzas\u0131 &#8220;<em><strong>(PARAMETRE_T\u0130PLER\u0130)GER\u0130_D\u00d6N\u00dc\u015e_T\u0130P\u0130<\/strong><\/em>&#8221; \u015feklinde olu\u015fur. Java taraf\u0131ndaki genel tiplerin JNI imzalar\u0131 Oracle&#8217;in\u00a0<a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/technotes\/guides\/jni\/spec\/types.html\" target=\"_blank\" rel=\"noopener\">dok\u00fcmantasyonuna<\/a> g\u00f6re \u015f\u00f6yledir:<\/p>\n<table>\n<tbody>\n<tr>\n<td style=\"text-align:center;\" width=\"101\"><strong>Java Tipi<\/strong><\/td>\n<td style=\"text-align:center;\" width=\"101\"><strong>Native Tipi<\/strong><\/td>\n<td style=\"text-align:center;\" width=\"101\"><strong>JNI \u0130mzasi<\/strong><\/td>\n<\/tr>\n<tr>\n<td style=\"text-align:left;\">boolean<\/td>\n<td style=\"text-align:left;\">jboolean<\/td>\n<td style=\"text-align:left;\">Z<\/td>\n<\/tr>\n<tr>\n<td>byte<\/td>\n<td>jbyte<\/td>\n<td>B<\/td>\n<\/tr>\n<tr>\n<td>char<\/td>\n<td>jchar<\/td>\n<td>C<\/td>\n<\/tr>\n<tr>\n<td>short<\/td>\n<td>jshort<\/td>\n<td>S<\/td>\n<\/tr>\n<tr>\n<td>int<\/td>\n<td>jint<\/td>\n<td>I<\/td>\n<\/tr>\n<tr>\n<td>long<\/td>\n<td>jlong<\/td>\n<td>J<\/td>\n<\/tr>\n<tr>\n<td>float<\/td>\n<td>jfloat<\/td>\n<td>F<\/td>\n<\/tr>\n<tr>\n<td>double<\/td>\n<td>jdouble<\/td>\n<td>D<\/td>\n<\/tr>\n<tr>\n<td>void<\/td>\n<td>void<\/td>\n<td>V<\/td>\n<\/tr>\n<tr>\n<td>Object<\/td>\n<td>jobject<\/td>\n<td>L&lt;PAKETADI&gt;<\/td>\n<\/tr>\n<tr>\n<td>Object[]<\/td>\n<td>jobjectArray<\/td>\n<td>[L&lt;PAKETADI&gt;<\/td>\n<\/tr>\n<tr>\n<td>boolean[]<\/td>\n<td>jbooleanArray<\/td>\n<td>[Z<\/td>\n<\/tr>\n<tr>\n<td>byte[]<\/td>\n<td>jbyteArray<\/td>\n<td>[B<\/td>\n<\/tr>\n<tr>\n<td>char[]<\/td>\n<td>jcharArray<\/td>\n<td>[C<\/td>\n<\/tr>\n<tr>\n<td>short[]<\/td>\n<td>jshortArray<\/td>\n<td>[S<\/td>\n<\/tr>\n<tr>\n<td>int[]<\/td>\n<td>jintArray<\/td>\n<td>[I<\/td>\n<\/tr>\n<tr>\n<td>long[]<\/td>\n<td>jlongArray<\/td>\n<td>[J<\/td>\n<\/tr>\n<tr>\n<td>float[]<\/td>\n<td>jfloatArray<\/td>\n<td>[F<\/td>\n<\/tr>\n<tr>\n<td>double[]<\/td>\n<td>jdoubleArray<\/td>\n<td>[D<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Java taraf\u0131nda implemente etti\u011finiz metod, bu tiplerden farkl\u0131 bir tipde veri kabul ediyorsa, \u00f6rne\u011fin String kabul eden bir metodunuz varsa ve bu method integer dizisi d\u00f6nd\u00fcr\u00fcyorsa method imzas\u0131 &#8220;<em><strong>(Ljava\/lang\/String)[I<\/strong><\/em>&#8221; olacakt\u0131r.<\/p>\n<p>Metod referans\u0131m\u0131z\u0131 da bulduktan sonra art\u0131k metodumuzu \u00e7a\u011f\u0131rabiliriz.<\/p>\n<pre>env-&gt;CallVoidMethod(instance, method, result);<\/pre>\n<p>Java taraf\u0131ndaki metodlar\u0131 \u00e7a\u011f\u0131r\u0131rken JNI headerinda bulunan tan\u0131ml\u0131 metodlar\u0131 kullanmam\u0131z gerekir. Bu methodlar \u00e7a\u011f\u0131rd\u0131\u011f\u0131m\u0131z metodun imzas\u0131na, geri d\u00f6n\u00fc\u015f tipine ve static olup olmad\u0131\u011f\u0131na g\u00f6re de\u011fi\u015fkenlik g\u00f6sterir. Bu methodlar Oracle\u00a0<a href=\"https:\/\/docs.oracle.com\/javase\/8\/docs\/technotes\/guides\/jni\/spec\/functions.html\" target=\"_blank\" rel=\"noopener\">dokumantasyonunda<\/a> belirtilmi\u015ftir.<\/p>\n<p>\u00d6zetle Java taraf\u0131ndan \u00e7a\u011f\u0131raca\u011f\u0131m\u0131z ve i\u00e7erisinde Java taraf\u0131na implemente etti\u011fimiz metodu \u00e7a\u011f\u0131racak kod \u015fu \u015fekilde olacakt\u0131r:<\/p>\n<pre>#include &lt;jni.h&gt;\n#include &lt;stddef.h&gt;\n\nextern \"C\" {\n JNIEXPORT void JNICALL\n Java_com_birfincankafein_hellojni_MainActivity_addAndLongToastNumbers(JNIEnv *env, jobject instance,\n jint number1, jint number2) {\n int result = ((int) number1) + ((int) number2);\n \/\/ We should find class before calling its method\n jclass clazz = env-&gt;FindClass(\"com\/birfincankafein\/hellojni\/MainActivity\");\n \/\/ (I)V means accepts int parameters and returns void\n jmethodID method = env-&gt;GetMethodID(clazz,\"makeToastLong__N\",\"(I)V\");\n if (method == 0) {\n \/\/ prevent crashed from method not found\n return;\n }\n env-&gt;CallVoidMethod(instance, method, result);\n }\n}<\/pre>\n<p>&nbsp;<\/p>\n<h3>3. Gradle Ayar\u0131<\/h3>\n<p>Android proje mod\u00fcl\u00fcm\u00fcz\u00fcn build script dosyas\u0131 olan <em>build.gradle<\/em> dosyas\u0131nda, yazd\u0131\u011f\u0131m\u0131z k\u00fct\u00fcphanemizi NDK-Build ile derlemek, Java taraf\u0131nda <em><strong>System.loadLibrary<\/strong><\/em> metodunda yazaca\u011f\u0131m\u0131z k\u00fct\u00fcphane ad\u0131n\u0131 belirlemek ve di\u011fer ayarlar i\u00e7in istedi\u011finiz <strong><em>build flavor<\/em><\/strong>&#8216;\u0131n\u0131zda a\u015fa\u011f\u0131daki kodlar\u0131 kullanabilirsiniz. \u00d6rnek projede bir build flavor olmad\u0131\u011f\u0131 i\u00e7in bu kodlar\u0131 Gradle&#8217;da <em><strong>android.defaultConfig<\/strong><\/em> alt\u0131nda kullanabiliriz.<\/p>\n<pre>ndk {\n    moduleName \"hello-jni\"\n    abiFilters 'armeabi', 'armeabi-v7a', 'x86'\n}<\/pre>\n<p>&nbsp;<\/p>\n<p>Art\u0131k \u00f6rnek uygulam\u0131z\u0131 \u00e7al\u0131\u015ft\u0131rabilir ve Toast mesajlar\u0131m\u0131z\u0131 g\u00f6rebiliriz. E\u011fer <em><strong>jniLibs<\/strong> <\/em>alt\u0131nda uygun i\u015flemci mimarisi klas\u00f6rlerinde harici native k\u00fct\u00fcphaneleriniz varsa bunlar otomatik olarak olu\u015fan apk i\u00e7erisine dahil edilecektir. Bu harici native k\u00fct\u00fcphaneleri de <em><strong>System.loadLibrary()<\/strong><\/em> kullanarak uygulaman\u0131zda kullanabilirsiniz.<\/p>\n<p>\u00d6rnek uygulamaya <a href=\"https:\/\/github.com\/birfincankafein\/metehantoksoy.com\/tree\/master\/Android\/Hello-JNI\" target=\"_blank\" rel=\"noopener\">GitHub<\/a>\u00a0\u00fczerinden ula\u015fabilirsiniz. Sormak istedi\u011finiz bir soru\u00a0olursa bu yaz\u0131n\u0131n alt\u0131na yorum yazabilir veya <a href=\"mailto:metehantoksoy@gmail.com\">email <\/a>adresimden bana e-posta\u00a0atabilirsiniz. Bir sonraki yaz\u0131larda g\u00f6r\u00fc\u015fmek dile\u011fiyle. Takipte kal\u0131n!<\/p>\n<p>&nbsp;<\/p>\n<h6 style=\"text-align:right;\">Kapak gorseli:\u00a0https:\/\/www.slideshare.net\/mauimauer\/android-ndk-and-the-x86-platform<\/h6>\n","protected":false},"excerpt":{"rendered":"<p>Merhaba arkada\u015flar. Uzun bir aradan sonra tekrar blog yazmaya ba\u015fl\u0131yorum. Bu yaz\u0131da e-posta\u00a0ile gelen sorular \u00fczerine biraz JNI \u00fczerinde duraca\u011f\u0131z. Bu yaz\u0131 giri\u015f niteli\u011finde olup JNI ile ileri d\u00fczeye sonraki yaz\u0131larda ge\u00e7ece\u011fiz. JNI Nedir? JNI (Java Native Interface), native kodlarla (C, C++) java kodlar\u0131n\u0131n konu\u015fabilmesi i\u00e7in geli\u015ftirilmi\u015f bir aray\u00fczd\u00fcr. JNI ile ilk cal\u0131\u015fmaya ba\u015flad\u0131\u011f\u0131mda kafamda &hellip; <a href=\"https:\/\/metehantoksoy.com\/?p=1014\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Android &#8211; Hello JNI&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":1059,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[13,2,16],"tags":[35,41,63,107,119,143,145,217],"class_list":["post-1014","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android","category-development","category-ndk","tag-android","tag-android-uygulama","tag-c","tag-fragment","tag-google","tag-java","tag-jni","tag-resimli-anlatim"],"jetpack_featured_media_url":"https:\/\/metehantoksoy.com\/wp-content\/uploads\/2017\/04\/android-ndk.jpg","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/metehantoksoy.com\/index.php?rest_route=\/wp\/v2\/posts\/1014","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/metehantoksoy.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/metehantoksoy.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/metehantoksoy.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/metehantoksoy.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1014"}],"version-history":[{"count":0,"href":"https:\/\/metehantoksoy.com\/index.php?rest_route=\/wp\/v2\/posts\/1014\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/metehantoksoy.com\/index.php?rest_route=\/wp\/v2\/media\/1059"}],"wp:attachment":[{"href":"https:\/\/metehantoksoy.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1014"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/metehantoksoy.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1014"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/metehantoksoy.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1014"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}