android java层通过jni加载使用第三方的so库
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
posted on 2017-11-13 13:14 luzhouxiaoshuai 阅读(6119) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!