1. 程式人生 > >Android呼叫JNI的簡單例項(附詳細步驟)

Android呼叫JNI的簡單例項(附詳細步驟)

最近想呼叫FFmepg庫來做編解碼的東西,首先就得學會使用JNI(JAVA Native Interface)呼叫。

下面做個簡單的JNI呼叫例項,中間遇到的問題及解決過程省略一萬字,查詢到的資料也都是東一句西一句的,整理一下完整的實現過程,希望對初學JNI的朋友有所幫助:

1、建立一個Android工程,名為SimpleJni;

2、在com.example.simplejni包下新建一個Jni介面類SimpleInterface,這個類不需要繼承java的介面類;

package com.example.simplejni;

public class SimpleInterface {
	public static native String sayName();
}
3、編譯這個介面類,為c端呼叫的標頭檔案。

工程目錄:


命令視窗: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工程,執行結果如下:


可以參考的文章: