Android呼叫JNI的簡單例項(附詳細步驟)
最近想呼叫FFmepg庫來做編解碼的東西,首先就得學會使用JNI(JAVA Native Interface)呼叫。
下面做個簡單的JNI呼叫例項,中間遇到的問題及解決過程省略一萬字,查詢到的資料也都是東一句西一句的,整理一下完整的實現過程,希望對初學JNI的朋友有所幫助:
1、建立一個Android工程,名為SimpleJni;
2、在com.example.simplejni包下新建一個Jni介面類SimpleInterface,這個類不需要繼承java的介面類;
3、編譯這個介面類,為c端呼叫的標頭檔案。package com.example.simplejni; public class SimpleInterface { public static native String sayName(); }
工程目錄:
命令視窗:Win+R執行cmd,cd進入到eclipse工作空間中SimpleJni工程目錄,
輸入javah -classpath bin/classes -d jni com.example.simplejni.SimpleInterface編譯介面類
編譯完成後,重新整理工程,就可以看到工程中自動建立了jni資料夾,其中包含編譯好的.h標頭檔案
4、事先安裝好NDT外掛,右鍵SimpleJni工程選擇Android tools下Add Native Support選項,library name使用預設的工程名;
完成後,會在jni資料夾中新增一個Android.mk檔案和SimpleJni.cpp檔案;
開啟標頭檔案,是不是發現JNICALL報錯了,不著急,下面有解決方法。
5、然後給工程新建並配置一個Builder,能夠自動生成so庫在Android端程式碼進行呼叫。
①右鍵工程-Properties-Builders-New,在彈出對話方塊中點選Program。
②在Edit Configuration對話方塊中的Main選項卡中,新增路徑;
Location中選擇到NDK安裝目錄下的ndk-build.cmd;
WorkingDirectory中選擇到SimpleJni工程目錄。
③選擇Refresh選項卡,在其中勾選如下
④在Build Options選項卡中勾選如下
其中Specify Resource中配置到SimpleJni工程的jni目錄即可。
到此點選ok,配置完成了,相比通過命令列編譯的方法,至少方便很多。
完成後,會在SimpleJni工程libs檔案下自動建立armeabi資料夾幷包含編譯好的libSimpleJni.so庫檔案,當工程有所改變的時候,就會自動編譯so檔案;
目前的工程目錄結構:
6、下面來填充SimpleJni.cpp,相信學過C++的朋友會覺得很熟悉,在這個cpp檔案裡面寫介面的具體實現。
這裡會出現JNICALL等型別無法識別等報錯,需要匯入一個NDK的include標頭檔案庫:
①右鍵工程,選擇Properties -> C/C++ General -> Path and Symbols 中點選include選項卡,新增NDK安裝目錄下的include資料夾D:\AndroidNDK\android-ndk-r10d\platforms\android-14\arch-arm\usr\include
匯入完畢之後就不會報錯了
7、首先將標頭檔案Include進來,但是要遵循方法的命名規則:Java_(固定開頭)com_example_hellojni(用"_"連線的包名)_HelloJni(類名)_stringFromJNI(函式名) 再從介面.h標頭檔案中把sayName方法複製過來,並修改引數,簡單的返回一個字串。
#include <jni.h>
#include <com_example_simplejni_SimpleInterface.h>
JNIEXPORT jstring JNICALL Java_com_example_simplejni_SimpleInterface_sayName
(JNIEnv *env, jclass){
return env->NewStringUTF("I'm Eric!");
}
8、然後修改MainActivity.java程式碼,新增一個TextView並設定其文字為SayName()方法的返回值;新增static程式碼塊,載入so庫,之前右鍵工程add native Support的library名稱就是在這裡呼叫:
package com.example.simplejni;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textview_id);
textView.setText(SimpleInterface.sayName());
}
static {
System.loadLibrary("SimpleJni");
}
}
執行SimpleJni工程,執行結果如下:
可以參考的文章: