eclipse下使用JNI
1. 在項目根目錄下創(chuàng)建jni文件夾 鞠苟,與src同級
2. 在jni文件中創(chuàng)建一個c文件后綴名為.c
/****這就是創(chuàng)建一個jni的native方法,用來調(diào)用c函數(shù)****/
3. 在java代碼中,創(chuàng)建一個本地方法,名字隨意发框,如helloFromc()方法豪娜,沒有方法體,連大括號也不要咽筋。
但是必須加關(guān)鍵字native,表明該方法是本地方法徊件,需要c語言來實現(xiàn)方法體晤硕。
public native String helloFromC();
/***這就是創(chuàng)建一個c函數(shù),供native層來調(diào)用庇忌,所以名字很重要***/
4. 在jni文件夾中定義C語言寫的函數(shù)實現(xiàn)這個方法舞箍,在c文件中添加頭文件 ,這樣才能識別jstring皆疹,env等那些東西
函數(shù)格式為
jni對應(yīng)的返回值類型 Java_包名_方法名(兩個必填參數(shù)){}
注意:數(shù)據(jù)類型不要搞錯疏橄;
Java的j是大寫;
包名里面的點最好都換成下劃線
JNIEnv* env:是一個java虛擬即的地址指針略就,是個二級指針捎迫,因為env本來就是一個指針,再*一下就是二級指針
jobject obj:調(diào)用該c方法的對象表牢,就這樣照寫
jstring Java_com_itheima_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj)//雖然本地native方法中helloFromc是無參方法窄绒,但是C語言中的必須加上這兩個參數(shù)
5. 返回一個字符串,用c定義一個字符串
char* cstr = "hello from c";
6. 把c的字符串轉(zhuǎn)換成java的字符串
jstring jstr = (*env)->NewStringUTF(env, cstr);
return jstr崔兴;
前面都是定義部分彰导,定義好C語言后要編譯,編譯就需要用到ndk工具來進行編譯敲茄,就要講法ndk配置進環(huán)境變量 位谋,
配制方法就是把 路徑:android-ndk-r9b 加進path
7. 在jni中創(chuàng)建Android.mk文件 ,文件里面的內(nèi)容:
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VERS)
編譯生成的類庫起個名字
LOCAL_MODULE:=heihei//這里同樣可以叫Hello
要編譯的C語言文件
LOCAL_SRC_FILES:=Hello.c
include $(BUILD_SHARED_LIBRARY)
8. 在jni文件夾下打開cmd后執(zhí)行ndk-build.cmd指令
9. java代碼中加載so類庫堰燎,調(diào)用本地方法掏父。寫在靜態(tài)代碼塊中Static{loadLibrary(“庫名”);}
-------------------mk文件詳解start--------------
# $是調(diào)用編譯工具鏈中的函數(shù), 這里的作用是獲取當(dāng)前文件目錄.
LOCAL_PATH := $(call my-dir)
# 清空并初始化編譯工具鏈的變量.
# 注意: 會清空所有的LOCAL_變量, 但不會清空LOCAL_PATH的變量.
include $(CLEAR_VARS)
# 編譯出來文件的名字, 編譯系統(tǒng)會在名字前加lib前綴. 如果已經(jīng)寫lib, 不會再添加.
# 注意: 不可以加擴展名.
LOCAL_MODULE := atguigu
# 指定編譯的源文件.如果多個源文件可以用空格連接起來
LOCAL_SRC_FILES := hello.c
# 指定編譯文件類型
# 動態(tài)庫(BUILD_SHARED_LIBRARY) 擴展名:.so 體積小.
# 靜態(tài)庫(BUILD_STATIC_LIBRARY) 擴展名:.a 體積大.
include $(BUILD_SHARED_LIBRARY)
----------------mk文件詳解end------------------
AS下使用JNI(as版本1.5完美秆剪,其他版本有問題)
1赊淑、在main下創(chuàng)建一個jni文件夾爵政,與java同級
2、3陶缺、4茂卦、5、6和eclipse一樣组哩。
然后在project的gradle.properties中添加配置 android.useDeprecatedNdk=true ,為了兼容老版本
7处渣、在app的build.gradle文件中的defaultConfig{}里面添加
ndk{
moduleName "Hello" //so文件: lib+moduleName+.so 伶贰,Hello就是后來要用的so庫名
abiFilters "armeabi", "armeabi-v7a", "x86" //cpu的類型
}
然后build項目,使項目生成so文件罐栈,生成的so文件在app?uildintermediates dkdebuglib下黍衙。
生成的鏈接庫名叫“l(fā)ibHello.so”,當(dāng)然我們也可以不寫這段代碼,也能編譯生成so庫荠诬,生成的名字是“l(fā)ibapp.so”,建議還是寫上琅翻,不然多了就不行了
在這里我們會發(fā)現(xiàn)步驟7不同,as的少了創(chuàng)建mk文件這個步驟柑贞,其實as已經(jīng)幫我們創(chuàng)建了方椎,因為我們的在gradle文件中進行了配置
8、回到本地方法native那里钧嘶,在寫native方法之前加載so庫棠众,System.loadLibrary("Hello");通常這行代碼寫在代碼塊或靜態(tài)代碼塊中。這樣一樣我們的native方法就會到Hello庫中去找與之對應(yīng)的c函數(shù)有决,其實我們更應(yīng)該在創(chuàng)建native方法的時候就這樣寫闸拿,后面要build之前確定moudleName是否與我們加載的這個庫名