设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间01 现在时间01 缓存数据 当你走完一段之后回头看,你会发现,那些真正能被记得的事真的是没有多少,真正无法忘记的人屈指可数,真正有趣的日子不过是那么一些,而真正需要害怕的也是寥寥无几。

当你走完一段之后回头看,你会发现,那些真正能被记得的事真的是没有多少,真正无法忘记的人屈指可数,真正有趣的日子不过是那么一些,而真正需要害怕的也是寥寥无几。

查看: 846|回复: 0

android studio如何通过 jni 调用第三方非标准 so库

[复制链接]

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
31
主题
29
精华
0
金钱
99
积分
60
注册时间
2023-10-3
最后登录
2025-9-8

发表于 2025-9-8 10:45:06 | 显示全部楼层 |阅读模式
调用第三方的so方法,但这个so内的方法不是标准的jni方法。这就需要我们自己写jni然后链接到第三方so库,通过jni调用so库中的方法。

1.简述:

要先有第三方的so库.so文件和编译库对应的.h头文件

  • 我们自己用 c/c++ 创建一个标准的so 库,比如 mynative.so
  • 然后用我们自己的mynative.so 库中去调用第三方的libnative.so库
  • 我们在上层 调用我们自己的mynativeso 库 ,就实现了对第三方 libnativeso 库 方法的调用。

2.先编译出一个第三方非标准so库


1).android studio 新创建一个项目

我们先制作一个非标准 jni 库,只要功能实现两个数相加 ,并返回相加后的结果。

2).main 新创建 jni 文件夹

1.png


3).新建 .cpp 文件和 .h 实现求和功能,并把文件放在jni目录下

test.cpp
  1. #include "test.h"
  2. Add::Add(){}
  3. Add::~Add(){}
  4. int Add::add(int x, int y){
  5.     return x + y;
  6. }
复制代码
test.h
  1. #ifndef _TEST_JNI_ADD_H_
  2. #define _TEST_JNI_ADD_H_
  3. class Add{
  4. public :
  5.     Add();
  6.     ~Add();
  7.     int add(int x, int y);
  8. };
  9. #endif
复制代码
2.png


4).编写 CMakeLists.txt 用来编译 cpp 文件为so库,在 app文件下新建CMakeLists.txt 文件

3.png
  1. #指定cmake最小版本
  2. cmake_minimum_required(VERSION 3.4.1)
  3. #设置生成的so动态库最后输出的路径
  4. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
  5. #生成so
  6. add_library( # 设置生成库的名字
  7.         nativeso
  8.         # 生成动态库
  9.         SHARED
  10.         # 指定源码文件,这里指定test.cpp文件
  11.         src/main/jni/test.cpp )
  12. #依赖的头文件
  13. INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/main/jni)
  14. find_library( # log库的别名
  15.         log-lib
  16.         #log库
  17.         log )
  18. #链接代码到指定的库
  19. target_link_libraries( # Specifies the target library.
  20.         nativeso
  21.         # Links the target library to the log library
  22.         # included in the NDK.
  23.         ${log-lib} )
复制代码
5).配置项目的build.gradle

4.png


6).配置 gradle.properties

5.png
  1. android.useDeprecatedNdk=true
复制代码
7).编译第三方非标准库,直接运行即可。

6.png


3.新建项目引用第三方 so 库


1)新建 android studio 项目


2)新建 java 类,封装想要调用的接口函数
  1. package com.example.demo05;
  2. public class JniCallNative {
  3.     static {
  4.         System.loadLibrary("mynativeso");
  5.     }
  6.     public static native  int  getAddFromNative(int a,int b);
  7. }
复制代码
3)Main 文件夹新建 jniLibs 文件夹,并拷贝第三方so到此文件夹下

7.png


4)创建 对应的 jni java 类文件的头文件

在Termial控制台中cd到项目目录中的源码目录下,并执行命令生成.h文件
  1.   javac -encoding utf-8 -h .  JniCallNative.java
复制代码
执行完成后,会在 java 目录生成 对应 .h 文件

5) main 文件夹 下新建 jni文件夹,实现底层逻辑


  • 将上一步 生成 .h 文件 拷贝进来,以及第三方so提供的对应.h头文件也要拷贝到jni目录中
  • 根据.h 文件 编写 对应的 .cpp 文件 ,在cpp 文件里实现对 第三方 so 库 的引用
  • 自己实现的逻辑中调用第三方.h内容
jninative.cpp 文件

  1. #include <jni.h>
  2. #include <string>
  3. #include <test.h>//导入需要的.h文件,这个是必须的,如果依赖的第三方库没有.h,需要自己编写
  4. extern "C"
  5. JNIEXPORT jint JNICALL Java_com_example_demo05_JniCallNative_getAddFromNative
  6.         (JNIEnv *, jclass, jint a, jint b){
  7.     //生成add对象并调用方法
  8.     Add addObj;
  9.     int result = addObj.add(a,b);
  10.     return result;
  11. }
复制代码
7) 编写 自己 so 库的 CMakeLists.txt 文件

app 文件下新建 CMakeLists.txt
8.png
  1. #指定cmake最小版本
  2. cmake_minimum_required(VERSION 3.4.1)
  3. #设置生成的so动态库最后输出的路径
  4. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
  5. #生成so
  6. add_library( # 设置生成库的名字
  7.         mynativeso
  8.         # 生成动态库
  9.         SHARED
  10.         # 指定源码文件,这里指定test.cpp文件
  11.         src/main/jni/jninative.cpp )
  12. #依赖的头文件
  13. INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src/main/jni)
  14. #依赖的add库
  15. add_library(nativeso SHARED IMPORTED)
  16. set_target_properties(nativeso
  17.         PROPERTIES IMPORTED_LOCATION
  18.         ${CMAKE_CURRENT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libnativeso.so)
  19. find_library( # log库的别名
  20.         log-lib
  21.         #log库
  22.         log )
  23. #链接代码到指定的库
  24. target_link_libraries( # Specifies the target library.
  25.         mynativeso
  26.         #add库需要链接
  27.         nativeso
  28.         # Links the target library to the log library
  29.         # included in the NDK.
  30.         ${log-lib} )
复制代码
8)  配置环境 build.gradle和 gradle.properties

9.png

10.png


9) 编译自己的so库,直接运行即可

11.png


10) 主函数调用测试

12.png
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"
  4.     xmlns:tools="http://schemas.android.com/tools"
  5.     android:id="@+id/main"
  6.     android:layout_width="match_parent"
  7.     android:layout_height="match_parent"
  8.     tools:context=".MainActivity">
  9.     <TextView
  10.         android:id="@+id/tv01"
  11.         android:layout_width="wrap_content"
  12.         android:layout_height="wrap_content"
  13.         android:text="Hello World!"
  14.         app:layout_constraintBottom_toBottomOf="parent"
  15.         app:layout_constraintEnd_toEndOf="parent"
  16.         app:layout_constraintStart_toStartOf="parent"
  17.         app:layout_constraintTop_toTopOf="parent" />
  18. </androidx.constraintlayout.widget.ConstraintLayout>
复制代码
13.png
  1. package com.example.demo05;
  2. import android.os.Bundle;
  3. import android.widget.TextView;
  4. import androidx.activity.EdgeToEdge;
  5. import androidx.appcompat.app.AppCompatActivity;
  6. import androidx.core.graphics.Insets;
  7. import androidx.core.view.ViewCompat;
  8. import androidx.core.view.WindowInsetsCompat;
  9. public class MainActivity extends AppCompatActivity {
  10.     @Override
  11.     protected void onCreate(Bundle savedInstanceState) {
  12.         super.onCreate(savedInstanceState);
  13.         EdgeToEdge.enable(this);
  14.         setContentView(R.layout.activity_main);
  15.         ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
  16.             Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
  17.             v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
  18.             return insets;
  19.         });
  20.         TextView textView = findViewById(R.id.tv01);
  21.         int addFromNative = JniCallNative.getAddFromNative(5, 5);
  22.         textView.setText(addFromNative + "");
  23.     }
  24. }
复制代码
14.png

到此这篇关于android studio通过 jni 调用第三方非标准 so库的文章就介绍到这了,更多相关android studio调用so库内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表