当前位置: 代码网 > it编程>App开发>Android > android studio如何通过 jni 调用第三方非标准 so库

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

2025年04月24日 Android 我要评论
调用第三方的so方法,但这个so内的方法不是标准的jni方法。这就需要我们自己写jni然后链接到第三方so库,通过jni调用so库中的方法。1.简述:要先有第三方的so库.so文件和编译库对应的.h头

调用第三方的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 文件夹

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

test.cpp

#include "test.h"
add::add(){}
add::~add(){}
int add::add(int x, int y){
    return x + y;
}

test.h

#ifndef _test_jni_add_h_
#define _test_jni_add_h_
class add{
public :
    add();
    ~add();
    int add(int x, int y);
};
#endif

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

#指定cmake最小版本
cmake_minimum_required(version 3.4.1)
#设置生成的so动态库最后输出的路径
set(cmake_library_output_directory ${cmake_source_dir}/src/main/jnilibs/${android_abi})
#生成so
add_library( # 设置生成库的名字
        nativeso
        # 生成动态库
        shared
        # 指定源码文件,这里指定test.cpp文件
        src/main/jni/test.cpp )
#依赖的头文件
include_directories(${cmake_current_source_dir}/src/main/jni)
find_library( # log库的别名
        log-lib
        #log库
        log )
#链接代码到指定的库
target_link_libraries( # specifies the target library.
        nativeso
        # links the target library to the log library
        # included in the ndk.
        ${log-lib} )

5).配置项目的build.gradle

6).配置 gradle.properties

android.usedeprecatedndk=true

7).编译第三方非标准库,直接运行即可。

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

1)新建 android studio 项目

2)新建 java 类,封装想要调用的接口函数

package com.example.demo05;
public class jnicallnative {
    static {
        system.loadlibrary("mynativeso");
    }
    public static native  int  getaddfromnative(int a,int b);
}

3)main 文件夹新建 jnilibs 文件夹,并拷贝第三方so到此文件夹下

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

在termial控制台中cd到项目目录中的源码目录下,并执行命令生成.h文件

  javac -encoding utf-8 -h .  jnicallnative.java

执行完成后,会在 java 目录生成 对应 .h 文件

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

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

jninative.cpp 文件

 
#include <jni.h>
#include <string>
#include <test.h>//导入需要的.h文件,这个是必须的,如果依赖的第三方库没有.h,需要自己编写
extern "c"
jniexport jint jnicall java_com_example_demo05_jnicallnative_getaddfromnative
        (jnienv *, jclass, jint a, jint b){
    //生成add对象并调用方法
    add addobj;
    int result = addobj.add(a,b);
    return result;
}
 

7) 编写 自己 so 库的 cmakelists.txt 文件

app 文件下新建 cmakelists.txt

#指定cmake最小版本
cmake_minimum_required(version 3.4.1)
#设置生成的so动态库最后输出的路径
set(cmake_library_output_directory ${cmake_source_dir}/src/main/jnilibs/${android_abi})
#生成so
add_library( # 设置生成库的名字
        mynativeso
        # 生成动态库
        shared
        # 指定源码文件,这里指定test.cpp文件
        src/main/jni/jninative.cpp )
#依赖的头文件
include_directories(${cmake_current_source_dir}/src/main/jni)
#依赖的add库
add_library(nativeso shared imported)
set_target_properties(nativeso
        properties imported_location
        ${cmake_current_source_dir}/src/main/jnilibs/${android_abi}/libnativeso.so)
find_library( # log库的别名
        log-lib
        #log库
        log )
#链接代码到指定的库
target_link_libraries( # specifies the target library.
        mynativeso
        #add库需要链接
        nativeso
        # links the target library to the log library
        # included in the ndk.
        ${log-lib} )
 

8)  配置环境 build.gradle和 gradle.properties

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

10) 主函数调用测试

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".mainactivity">
    <textview
        android:id="@+id/tv01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hello world!"
        app:layout_constraintbottom_tobottomof="parent"
        app:layout_constraintend_toendof="parent"
        app:layout_constraintstart_tostartof="parent"
        app:layout_constrainttop_totopof="parent" />
</androidx.constraintlayout.widget.constraintlayout>

package com.example.demo05;
import android.os.bundle;
import android.widget.textview;
import androidx.activity.edgetoedge;
import androidx.appcompat.app.appcompatactivity;
import androidx.core.graphics.insets;
import androidx.core.view.viewcompat;
import androidx.core.view.windowinsetscompat;
public class mainactivity extends appcompatactivity {
    @override
    protected void oncreate(bundle savedinstancestate) {
        super.oncreate(savedinstancestate);
        edgetoedge.enable(this);
        setcontentview(r.layout.activity_main);
        viewcompat.setonapplywindowinsetslistener(findviewbyid(r.id.main), (v, insets) -> {
            insets systembars = insets.getinsets(windowinsetscompat.type.systembars());
            v.setpadding(systembars.left, systembars.top, systembars.right, systembars.bottom);
            return insets;
        });
        textview textview = findviewbyid(r.id.tv01);
        int addfromnative = jnicallnative.getaddfromnative(5, 5);
        textview.settext(addfromnative + "");
    }
}

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

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com