android 调用JNI SO动态库的方法
程序员文章站
2022-03-13 10:53:35
总结一下:android 调用jni 分为静态调用与动态调用(不论动态还是静态前提都是ndk环境已经配置好的前提下)一、静态主要就是将c(.c)或者c++(cpp)的源文件直接加到项目中进行调用,然后...
总结一下:
android 调用jni 分为静态调用与动态调用(不论动态还是静态前提都是ndk环境已经配置好的前提下)
一、静态主要就是将c(.c)或者c++(cpp)的源文件直接加到项目中进行调用,
然后在cmakelists.txt中进行配置。
二、动态调用
1、动态调用使用已经编译好的动态库.so文件
2、android调用ndk类
生成后的so文件
public class serialport { p */ public static native int getsover(string ar); static { system.loadlibrary("serialport");//初始化so库(注意这里添加是需要去掉lib与.so) } }
3、.c文件添加
/* * copyright 2009-2011 cedric priscal * * licensed under the apache license, version 2.0 (the "license"); * you may not use this file except in compliance with the license. * you may obtain a copy of the license at * * http://www.apache.org/licenses/license-2.0 * * unless required by applicable law or agreed to in writing, software * distributed under the license is distributed on an "as is" basis, * without warranties or conditions of any kind, either express or implied. * see the license for the specific language governing permissions and * limitations under the license. */ #include <jni.h> #include <termios.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include "m1900_drv.h" #include "serialport.h" #include "include/tinyalsa/audio_i2s.h" #include "include/tinyalsa/asoundlib.h" #include "android/log.h" #include "newland_linux_so.h" static const char *tag = "serial_port"; #define logi(fmt, args...) __android_log_print(android_log_info, tag, fmt, ##args) #define logd(fmt, args...) __android_log_print(android_log_debug, tag, fmt, ##args) #define loge(fmt, args...) __android_log_print(android_log_error, tag, fmt, ##args) //测试 java_(固定)_com_littt_util_serialport(android包名原来的.更改为_,string ar 传入的字符串参数,jnienv *env, jclass固定写法) jniexport jint jnicall java_com_littt_util_serialport_getsover(jnienv *env, jclass clazz, jstring ar) { // todo: implement getsover() return 9;//返回一个9的值 }
4、.h头文件中声明
/* do not edit this file - it is machine generated */ #include <jni.h> /* header for class android_serialport_api_serialport */ #ifndef _included_android_serialport_api_serialport #define _included_android_serialport_api_serialport #ifdef __cplusplus extern "c" { #endif jniexport jint jnicall java_com_littt_util_serialport_getsover(jnienv *env, jclass clazz,jstring v); #ifdef __cplusplus } #endif #endif
5、头文件与c文件写好了,就需要在cmake 中添加.c与.h都需要添加
# for more information about using cmake with android studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html # sets the minimum version of cmake required to build the native library. cmake_minimum_required(version 3.4.1) # creates and names a library, sets it as either static # or shared, and provides the relative paths to its source code. # you can define multiple libraries, and cmake builds them for you. # gradle automatically packages shared libraries with your apk. add_library( # sets the name of the library. serialport # sets the library as a shared library. shared # provides a relative path to your source file(s). m1900_drv.c m1900_drv.h audio_i2s.c linux_so.cpp mixer.c include/tinyalsa/asoundlib.h include/tinyalsa/audio_i2s.h ) # searches for a specified prebuilt library and stores the path as a # variable. because cmake includes system libraries in the search path by # default, you only need to specify the name of the public ndk library # you want to add. cmake verifies that the library exists before # completing its build. find_library( # sets the name of the path variable. log-lib # specifies the name of the ndk library that # you want cmake to locate. log) # specifies libraries cmake should link to your target library. you # can link multiple libraries, such as libraries you define in this # build script, prebuilt third-party libraries, or system libraries. target_link_libraries( # specifies the target library. serialport # links the target library to the log library # included in the ndk. ${log-lib}) set(cmake_c_flags_release "${cmake_c_flags_release} -s") set(cmake_cxx_flags_release "${cmake_cxx_flags_release} -s")
6、在build.gradle同样需要配置
plugins { id 'com.android.application' } android { compilesdkversion 28 buildtoolsversion "28.0.3" defaultconfig { applicationid "com.littt.interphone" minsdkversion 17 targetsdkversion 28 versioncode 1 versionname "1.0" testinstrumentationrunner "androidx.test.runner.androidjunitrunner" // cmake externalnativebuild { cmake { cppflags "" abifilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' } } } externalnativebuild { cmake { path "src/main/cpp/cmakelists.txt" version "3.10.2" } } buildtypes { release { minifyenabled false proguardfiles getdefaultproguardfile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } sourcesets { main { jnilibs.srcdirs = ['libs'] } } compileoptions { sourcecompatibility javaversion.version_1_8 targetcompatibility javaversion.version_1_8 } ndkversion '22.1.7171670' } dependencies { // implementation 'androidx.appcompat:appcompat:1.2.0' // implementation 'com.google.android.material:material:1.2.1' }
7、如果静态调用可以成功,那么就可以生成动态so库文件
点击图中锤子会进行编译。完成后可以打开如下路径查看
红框中生成后 so文件
7.1、生成的.so文件(工程文件夹模式)目录为app/build/intermediates/ndk/lib,将其复制到另一个工程的app/lib目录下。
7.2、要使用上述的.so文件 ,必须将工程的包名改为生成.so文件时的包名,要不然 编译能通过,但是app不能正常运行。logcat会提示找不到所调用函数的实现。
7.3、将so文件复制到需要的路径下。
7.4、在gradle.properties中最后加一行:android.usedeprecatedndk=true。
到此这篇关于android 调用jni so动态库的文章就介绍到这了,更多相关android 调用jni so动态库内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
上一篇: Python展示文件下载进度条
推荐阅读
-
Python调用C/C++动态链接库的方法详解
-
linux中使用boost.python调用c++动态库的方法
-
Android Studio中导入JNI生成的.so库的实现方法
-
【Android】动态链接库so的加载原理
-
android 调用JNI SO动态库的方法
-
安卓串口库android_serialport_api的简单移植方法,以及一些使用细节(有.so动态库的前提下)
-
Qt之调用C#的动态库的解决方法
-
jna使用之(三)java调用动态库dll/so-设计自己的加载动态库框架
-
php动态调用函数方法&&非关系数据库的优势
-
Android JNI实现Java与C/C++互相调用,以及so库的生成和调用(JNI方式调用美图秀秀so)