1、例如我們自己編譯一個so庫,我們的其他模塊要加載如何操作了
首先在c盤新建立一個文件夾sb,在sb下面新建立一個文件夾jni,如果你要使用ndk編譯so庫,必須需要有jni目錄
2、在jni目錄下面建立下面幾個文件
我們來看看c文件
// // Created by wei.yuan on 2017/11/2. // #include<jni.h> #include<logback_ecmapplication_cetcs_com_myapplicationkldsk_JNI.h> #include <jni.h> #include <string.h> #include <pthread.h> JNIEXPORT jstring JNICALL Java_logback_ecmapplication_cetcs_com_myapplicationkldsk_JNI_getStringFromC (JNIEnv *env, jobject obj){ int *a = (int *) (NULL); *a = 1; return (*env)->NewStringUTF(env,"I'm comes from 5454552444444to Native Function!"); }
然后是頭文件
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity */ #ifndef _Included_logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity #define _Included_logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity #ifdef __cplusplus extern "C" { #endif #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_ABOVE_CLIENT #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_ABOVE_CLIENT 8L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_ADJUST_WITH_ACTIVITY #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_ADJUST_WITH_ACTIVITY 128L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_ALLOW_OOM_MANAGEMENT #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_ALLOW_OOM_MANAGEMENT 16L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_AUTO_CREATE #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_AUTO_CREATE 1L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_DEBUG_UNBIND #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_DEBUG_UNBIND 2L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_IMPORTANT #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_IMPORTANT 64L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_NOT_FOREGROUND #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_NOT_FOREGROUND 4L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_WAIVE_PRIORITY #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_BIND_WAIVE_PRIORITY 32L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_CONTEXT_IGNORE_SECURITY #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_CONTEXT_IGNORE_SECURITY 2L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_CONTEXT_INCLUDE_CODE #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_CONTEXT_INCLUDE_CODE 1L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_CONTEXT_RESTRICTED #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_CONTEXT_RESTRICTED 4L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_APPEND #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_APPEND 32768L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING 8L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_MULTI_PROCESS #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_MULTI_PROCESS 4L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_PRIVATE #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_PRIVATE 0L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_WORLD_READABLE #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_WORLD_READABLE 1L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_WORLD_WRITEABLE #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_MODE_WORLD_WRITEABLE 2L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_DIALER #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_DIALER 1L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_DISABLE #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_DISABLE 0L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_SHORTCUT #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_DEFAULT_KEYS_SHORTCUT 2L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_RESULT_CANCELED #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_RESULT_CANCELED 0L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_RESULT_FIRST_USER #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_RESULT_FIRST_USER 1L #undef logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_RESULT_OK #define logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity_RESULT_OK -1L /* * Class: logback_ecmapplication_cetcs_com_myapplicationkldsk_MainActivity * Method: getStringFromC * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_logback_ecmapplication_cetcs_com_myapplicationkldsk_JNI_getStringFromC (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
現在我們要生成so庫,需要配置android.mk文件和application.mk文化
android.mk文件內容如下所示:
ROOT_PATH := $(call my-dir) LOCAL_PATH := $(ROOT_PATH) include $(CLEAR_VARS) LOCAL_MODULE := sb_jni LOCAL_SRC_FILES := logback_ecmapplication_cetcs_com_myapplicationkldsk_JNI.c LOCAL_CFLAGS := -Wl,-g LOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY)
application.mk文件如下所示:
APP_STL := stlport_static APP_ABI := all APP_CXXFLAGS := -std=c++11 -D__STDC_LIMIT_MACROS APP_PLATFORM := android-12
有了上面的配置之后,我們就可以在cgwin環境中生成對應的so庫文件了,cgwin進入到對應的jni目錄,使用ndk-build命令
編譯成功之后會在jni的目錄下產生下面的兩個文件夾
libs文件下面的so庫就是可以提高給第三方使用的so庫,obj目錄下生成的so庫就是具有調試信息的so庫,當發現奔潰的時候,可以使用工具arm-linux-androideabi-addr2line.exe解決該obj目錄下的so庫來定位文件
現在我們在android studio下面新建立一個工程
我們將上面的libs目錄拷貝到工程和src同級別的目錄下
然后在工程的gradle文件中配置下面的代碼
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
完成的gradle代碼如下
apply plugin: 'com.android.application' android { compileSdkVersion 24 buildToolsVersion "24.0.2" defaultConfig { applicationId "cn.onlinecache.breakpad" minSdkVersion 9 targetSdkVersion 24 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets { main { jniLibs.srcDirs = ['libs'] } } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile project(':breakpad') compile 'com.android.support:appcompat-v7:24.2.1' compile 'com.jakewharton:butterknife:8.4.0' compile 'com.android.support.constraint:constraint-layout:1.0.2' testCompile 'junit:junit:4.12' annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0' }
通過上面的配置,我們編譯工程就會自動生成jNIlibs目錄
然后我們要在代碼中使用so庫中的函數,如何使用了
JNIEXPORT jstring JNICALL Java_logback_ecmapplication_cetcs_com_myapplicationkldsk_JNI_getStringFromC
(JNIEnv *env, jobject obj){ int *a = (int *) (NULL); *a = 1; return (*env)->NewStringUTF(env,"I'm comes from 5454552444444to Native Function!"); }
從c語言中我們可以看出,這個函數是 通過JNI編程規范編寫的,必須要滿足JNI的編程規范,通過
JNIEXPORT jstring JNICALL Java_logback_ecmapplication_cetcs_com_myapplicationkldsk_JNI_getStringFromC我們可以知道對應該函數的java層對應的
包名是
logback.ecmapplication.cetcs.com.myapplicationkldsk
對應的類名是JNI,對應的函數名是
getStringFromC
所以我們在工程中應該要建立下面的這樣一個文件
package logback.ecmapplication.cetcs.com.myapplicationkldsk; /** * Created by wei.yuan on 2017/11/13. */ public class JNI { public native String getStringFromC(); static { System.loadLibrary("sb_jni"); } }
在這個文件中加載so 庫進行調用
調用者:
new JNI().getStringFromC()
工程結構如下:
工程項目代碼如下所示:
http://pan.baidu.com/s/1nvHuufB