最近在項目中須要使用JNI的相關東西,尤爲是.so文件,發現許多開發者都是很是陌生的,因此有必要在這裏作個簡單的介紹。javascript
早起Android只支持ARMv5的CPU架構,而發展到如今,支持一下7種架構:
ARMv5:如今不多了,應該不須要支持了
ARMv7(2010年起):魅族M9,iphone 3GS,三星I9000等
x86(2011年起):聯想K800,使用這種架構的較少,畢竟Android手機大部分是ARM。
MIPS(2012年):可能有些國產廠商在用
ARMv8:華爲 Mate 8,Galaxy S
MIPS64:暫時沒發現什麼手機在用
x86_64(2014年):64位平板
每種架構關聯着一種ABI(application binary interface應用程序二進制接口),因此每一種架構都對應一個.so文件。
如圖所示:java
這裏須要注意很重要的一點:
arm64-v8a是能夠向下兼容的,但前提是你的項目裏面沒有arm64-v8a的文件夾,若是你有兩個文件夾armeabi和arm64-v8a,兩個文件夾,armeabi裏面有a.so 和 b.so,arm64-v8a裏面只有a.so,那麼arm64-v8a的手機在用到b的時候發現有arm64-v8a的文件夾,發現裏面沒有b.so,就報錯了,因此這個時候刪掉arm64-v8a文件夾,這個時候手機發現沒有適配arm64-v8a,就會直接去找armeabi的so庫,因此要麼你別加arm64-v8a,要麼armeabi裏面有的so庫,arm64-v8a裏面也必須有。android
對於eclipse就不用多說了,放在libs中便可。
若是使用Android Studio,有兩種方式能夠依賴.so文件
第一種放在src/main/jniLibs中如圖所示:c++
第二種方式,也能夠放到libs中,可是須要在build.gradle中設置一下目錄結構:架構
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}複製代碼
在app的build.gradle中:app
defaultConfig {
applicationId "umeng.testjni"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
ndk {
moduleName "JniTest"
ldLibs "log", "z", "m"
abiFilters "armeabi", "armeabi-v7a", "x86"
}
}複製代碼
其中moduleName是生成的.so文件的名字,若是設置成JniTest,生成的.so文件會是libJniTest.so,ldLibs是依賴的庫。
打開gradle.properties文件,增長配置:eclipse
android.useDeprecatedNdk = true複製代碼
local.properties增長ndk的配置路徑:iphone
ndk.dir=/Users/xxxx/xxxx/sdk/android-ndk-r10e
sdk.dir=/Users/xxxxx/Library/Android/sdk複製代碼
而後在工程中創建調用jni的文件:gradle
public class UmengJni {
static {
System.loadLibrary("JniTest");
}
public static native String sayHello();
}複製代碼
其中 System.loadLibrary("JniTest");是加載.so文件,sayHello是c++的方法名字。
這時打開命令行,切到當前應用工程的目錄下,輸入以下命令:ui
其中umeng.testjni.UmengJni是咱們剛剛編寫的文件,這時會在對應的路徑下生成一個.h文件
#include <jni.h>
/* Header for class umeng_testjni_UmengJni */
#ifndef _Included_umeng_testjni_UmengJni
#define _Included_umeng_testjni_UmengJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: umeng_testjni_UmengJni
* Method: sayHello
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_umeng_testjni_UmengJni_sayHello
(JNIEnv *env, jclass object){
return (*env)->NewStringUTF(env,"JNI hahahahahahahaha");
}
#ifdef __cplusplus
}
#endif
#endif複製代碼
此時運行便可編譯.so文件,在build/intermediates/ndk目錄下能夠找到對應文件:
*更多的開發知識,能夠關注個人公衆號: