千家信息网

android调用JNI SO动态库的方法是什么

发表于:2025-01-16 作者:千家信息网编辑
千家信息网最后更新 2025年01月16日,这篇文章主要介绍"android调用JNI SO动态库的方法是什么",在日常操作中,相信很多人在android调用JNI SO动态库的方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作
千家信息网最后更新 2025年01月16日android调用JNI SO动态库的方法是什么

这篇文章主要介绍"android调用JNI SO动态库的方法是什么",在日常操作中,相信很多人在android调用JNI SO动态库的方法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"android调用JNI SO动态库的方法是什么"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

一、静态主要就是将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 #include #include #include #include #include #include #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 /* Header for class android_serialport_api_SerialPort */#ifndef _Included_android_serialport_api_SerialPort#define _Included_android_serialport_api_SerialPort#ifdef __cplusplusextern "C" {#endifJNIEXPORT jint JNICALLJava_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动态库的方法是什么"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0