說明:本文是傳統(tǒng)so生成方案,最新的有cmake方式互捌,具體請參見:http://www.reibang.com/p/9fe0f55fe962惑畴。
JNI(Java Native Interface | Java 本地接口)
1、下載ndk
如圖所示1寡夹、2处面、3、4
說明
2菩掏、配置SDK location
打開如下頁面魂角,第三步的時候點擊
select default ndk
會自動識別默認路徑
3、創(chuàng)建類
- 創(chuàng)建類
public class JNITest {
//創(chuàng)建一個 native 方法
public native static String get();
}
-
點擊make project
這樣就可以生成對應的class 文件
4智绸、創(chuàng)建頭文件
- 終端使用命令進入main目錄
cd src/main
- 使用下方命令創(chuàng)建 .h 的頭文件
javah -d jni -classpath /Users/zhangdake/AndroidStudioProjects/DemoAll/sample/build/intermediates/classes/debug com.canzhang.sample.manager.jni.JNITest
命令的簡單介紹
javah:生成頭文件
-d jni:當前目錄下創(chuàng)建一個 jni 文件夾
-classpath .../debug 指定要生成頭文件的字節(jié)碼文件目錄野揪,即我們剛剛的 JNITest.class 的目錄
com.canzhang.sample.manager.jni.JNITest 是 JNITest 文件的包名加上字節(jié)碼文件的名稱
注意:這個 debug 文件目錄可能太長访忿,輸入麻煩,我們可以找到 debug 文件夾斯稳,右鍵 copy path海铆,復制文件目錄即可
- 現(xiàn)在我們可以看到 app/src/main 目錄下有一個 jni 文件夾,里面有一個 com_canzhang_sample_manager_jni_JNITest.h 的頭文件挣惰,就是我們生成的頭文件游添,頭文件命名也是按照包名加字節(jié)碼名的規(guī)范,以下劃線連接通熄。
5唆涝、創(chuàng)建c文件
在上方生成的jni目錄內創(chuàng)建
注意:目錄不要放錯,方法內的包名也不要寫錯
#include<jni.h>
#include<stdio.h>
//導入我們創(chuàng)建的頭文件,注意包名要正確
#include "com_canzhang_sample_manager_jni_JNITest.h"
//注意包名不要弄錯
JNIEXPORT jstring Java_com_canzhang_sample_manager_jni_JNITest_get
(JNIEnv *env, jclass jclass){
//返回一個字符串
return (*env)->NewStringUTF(env,"我來自c");
}
5唇辨、創(chuàng)建mk文件
同樣也是在jni目錄內創(chuàng)建
-
Android.mk
(不能隨意添加注釋字符廊酣,容易報錯)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:=JNITest
LOCAL_SRC_FILES:=test.c
include $(BUILD_SHARED_LIBRARY)
-
Application.mk
(不能隨意添加注釋字符,容易報錯)
APP_ABI := all//全平臺
示例圖
6赏枚、生成so庫
cd 到 app/src/main/jni 目錄下亡驰,使用 ndk-build
(注意中間有個橫杠,另外這里要使用這個命令饿幅,需要配置下ndk的環(huán)境變量)命令生成 so 庫:
然后就可以看到這些庫了
如果有亂碼提示凡辱,則查看mk文件中是否配置有中文字符
如果出現(xiàn)警告
Android NDK: WARNING: APP_PLATFORM android-14 is higher than android:minSdkVersion 1 in F:/workspace/DemoAll/DemoAll/sample/src/main/AndroidManifest.xml. NDK binaries will *not* be comptible with devices older than android-14.
則可以在清單文件中添加
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="26"></uses-sdk>
7、使用so庫
- 為了讓項目能夠找到我們的 so 庫栗恩,在主module下的 build.gradle 文件夾的 android 下添加:
sourceSets {
main() {
jniLibs.srcDirs = ['src/main/libs']
jni.srcDirs = [] //disable automatic ndk-build call, which ignore our Android.mk
}
}
- 然后我們在 JNITest.java 中動態(tài)導入 so 庫透乾,不需要寫 libJNITest泼疑,只用寫 JNITest:
public class JNITest {
// 動態(tài)導入 so 庫
static {
System.loadLibrary("JNITest");
}
//創(chuàng)建一個 native 方法
public native static String get();
}
- 使用
String s = JNITest.get()
這樣獲取的返回值就是 我們在c中的返回值了