首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

android studio 3.2 cmake jni调用第三方库动态库

  • 23-12-06 23:22
  • 2667
  • 13846
blog.csdn.net

jni的基本使用方法请看我的另外一篇博客

http://iyenn.com/rec/1806082.htmlhttps://mp.csdn.net/postedit/83825826

 

总体思路:

  1. 新建一个my.cpp和my.h文件
  2. 利用android studio中的cmake工具将my.cpp编译成全架构(armeabi-v7a,arm64-v8a,x86,x86_64)的库文件。编译时很多问题,报错时出现x86或者armeabi都是因为没有对应的架构造成的,我们索性就直接造一个全架构的库。
  3. 将第2步中生成的库链接到native-lib.so(系统自动生成的库)中
  4. 运行,看在native-lib.cpp中的函数能否调用my.cpp中的函数

我们从头开始,最好新建立一个文件。

1.建立jni文件

不多说,看http://iyenn.com/rec/1806082.htmlhttps://mp.csdn.net/postedit/83825826

建立好之后先运行app,看能否运行,不能运行就先百度解决,正常运行之后再进行后面的操作


2.新建my.cpp和my.h

1.在Project视图下 app/src/main/cpp 目录下创建my.cpp同时创建头文件my.h

2.在my.cpp写一个函数,并且添加android的日志库,以便知道当前函数是否被正确被调用

my.h如下:

  1. #ifndef JNITEST2_MY_H
  2. #define JNITEST2_MY_H
  3. //-----------------------------横线里面的内容为新增--------------------------
  4. #include
  5. #define LOG "JNILOG"
  6. #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG,__VA_ARGS__)
  7. #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG,__VA_ARGS__)
  8. #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG,__VA_ARGS__)
  9. #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG,__VA_ARGS__)
  10. #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG,__VA_ARGS__)
  11. int my_fun();
  12. //-------------------------------------------------------------------------
  13. #endif //JNITEST2_MY_H

my.cpp

  1. #include "my.h"
  2. //-----------------------------横线里面的内容为新增--------------------------
  3. int my_fun()
  4. {
  5. LOGD("android studio jni");
  6. return 111;
  7. }
  8. //-------------------------------------------------------------------------

3.将my.cpp编译成全架构的.so库

1.修改CMakeLists.txt,只新增了两句,原来的不需要改

  1. cmake_minimum_required(VERSION 3.4.1)
  2. add_library(native-lib SHARED src/main/cpp/native-lib.cpp)
  3. #-----新增--------
  4. add_library(my-lib SHARED src/main/cpp/my.cpp)
  5. find_library(log-lib log)
  6. target_link_libraries(native-lib ${log-lib})
  7. #-----新增---------------
  8. target_link_libraries(my-lib ${log-lib})

2.修改app级别下的build.gradle新增一句

3.点击make project

4.编译成功之后,查看生成的库

    在Project目录下   app/build/intermediates/cmake/debug/obj/各种架构

    libmy-lib.so就是我们需要链接到libnative-lib.so的库

4.将libmy-lib.so链接到native-lib.so

1.修改CMakeLists.txt文件

  1. cmake_minimum_required(VERSION 3.4.1)
  2. add_library(native-lib SHARED src/main/cpp/native-lib.cpp)
  3. #-----删除--------
  4. #add_library(my-lib SHARED src/main/cpp/my.cpp)
  5. #-----新增---------
  6. add_library(apple SHARED IMPORTED)
  7. #-----新增---------
  8. set_target_properties(apple PROPERTIES IMPORTED_LOCATION
  9. ${CMAKE_CURRENT_SOURCE_DIR}/build/intermediates/cmake/debug/obj/${CMAKE_ANDROID_ARCH_ABI}/libmy-lib.so
  10. )
  11. find_library(log-lib log)
  12. #------修改---------
  13. target_link_libraries(native-lib apple ${log-lib})
  14. #-----删除---------------
  15. #target_link_libraries(my-lib ${log-lib})

#删除的就表示不要了,#新增就表示新添加的,#修改就表示在原来的基础上修改

说明一下set_target_properties这里面的参数。

${CMAKE_CURRENT_SOURCE_DIR} 表示app这个文件夹,也可以用别的参数来表示。因为Android studio的版本不同,参数可能回不一样,但是一定要能定位到cmake/debug/obj这个文件夹。可以用ctrl+左键来试一下能否被识别。

${CMAKE_ANDROID_ARCH_ABI}表示系统会根据自己的要求去不同的架构目录下去寻找libmy-lib.so,所以不要指定单独的文件夹

2.在native-lib.cpp中调用我们my.cpp的函数

  1. #include
  2. #include
  3. //---------新增
  4. #include "my.h"
  5. extern "C" JNIEXPORT jstring JNICALL
  6. Java_com_example_tuweiguang_jnitest2_MainActivity_stringFromJNI(
  7. JNIEnv *env,
  8. jobject /* this */) {
  9. std::string hello = "Hello from C++";
  10. //-----------新增-------------
  11. int x = 0;
  12. x = my_fun();
  13. LOGD("x = %s",x);
  14. //---------------------------
  15. return env->NewStringUTF(hello.c_str());
  16. }

5.运行app

点击运行app

成功调用


至此,jni调用第三方库的教程结束。

还有一些其他问题,目前本人也正在学习,希望共勉:

1.如果我们手里只有单一架构的库,任然希望就在这种架构的及其上运行这种单一架构的库

2.如果你有任何问题,也可以留言,一起讨论

今天无意间发现了一个神奇的事件paste, 下面来介绍一下吧。

为了测试粘贴复制,下面我们先来写一个点击复制的工具函数

js
代码解读
复制代码
const clipboard = (text) => { return new Promise((resolve, reject) => { // 创建隐藏的 Textarea 标签,并将文本放入其中 let textarea = document.createElement('textarea') textarea.style.position = 'absolute' textarea.style.top = '0' textarea.style.left = '0' textarea.style.border = 'none' textarea.style.margin = '0' textarea.style.padding = '0' textarea.style.opacity = '0' textarea.value = text document.body.appendChild(textarea) // 复制 Textarea 标签的文本 textarea.select() document.execCommand('copy') // 移除 Textarea 标签 document.body.removeChild(textarea) resolve() }) }

paste事件:当用户在浏览器用户界面发起“粘贴”操作时,会触发 paste 事件。

这个只会作用于可输入文本的dom元素上。如果都不可输入,那么我们整个页面也是可以触发的。

下面来看一下例子。

html
代码解读
复制代码
html> <html lang="en" contenteditable="false"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Documenttitle> head> <body> <div>页面中没有可以可输入文本的dom元素div> <script> document.addEventListener("paste", function(e) { console.log("e", e) }) script> body> html>

image.png 下面我们让div变成可以输入文本的dom。

html
代码解读
复制代码
html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Documenttitle> <style> div { width: 300px; height: 300px; background: skyblue; } style> head> <body> <div contenteditable="true"> 我是可输入文本的div div> <script> const div = document.getElementsByTagName("div")[0] // 这个事件只作用于可编辑的dom元素上。 // 如果元素都没有设置contenteditable="true",那么将作用于整个网页。 div.addEventListener("paste", function(e) { console.log("e", e) }) script> body> html>

paste测试.gif 上面可以看出,只有光标聚焦到div元素上时执行粘贴行为时,才会触发paste事件。

开始的时候我只是想获取剪切板中粘贴的图片对象。就像掘金编辑器一样,平常就是在别的地方拷贝图片到文章中。

我们可以这样获取粘贴的图片对象。然后就可以上传到服务器了。

html
代码解读
复制代码
html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Documenttitle> <style> div { width: 300px; height: 300px; background: skyblue; } style> head> <body> <div contenteditable="true"> 我是可输入文本的div div> <script> const div = document.getElementsByTagName("div")[0] // 这个事件只作用于可编辑的dom元素上。 // 如果元素都没有设置contenteditable="true",那么将作用于整个网页。 div.addEventListener("paste", function(e) { // 明明打印e.clipboardData.item没有值,但是最后获取getAsFile时,就可以打印出来。 console.log("e:获取文件对象",e.clipboardData.items[0].getAsFile() ) }) script> body> html>

paste测试获取文件对象.gif

那么获取文件对象会了,那么如何获取普通的复制的文本呢?

事件处理程序可以通过调用事件的 clipboardData 属性上的 getData()访问剪贴板内容。

html
代码解读
复制代码
html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Documenttitle> <style> div { width: 300px; height: 300px; background: skyblue; } style> head> <body> <div contenteditable="true"> 我是可输入文本的div div> <p>点我复制p> <script> const clipboard = (text) => { return new Promise((resolve, reject) => { // 创建隐藏的 Textarea 标签,并将文本放入其中 let textarea = document.createElement('textarea') textarea.style.position = 'absolute' textarea.style.top = '0' textarea.style.left = '0' textarea.style.border = 'none' textarea.style.margin = '0' textarea.style.padding = '0' textarea.style.opacity = '0' textarea.value = text document.body.appendChild(textarea) // 复制 Textarea 标签的文本 textarea.select() document.execCommand('copy') // 移除 Textarea 标签 document.body.removeChild(textarea) resolve() }) } const div = document.getElementsByTagName("div")[0] const p = document.getElementsByTagName("p")[0] // 这个事件只作用于可编辑的dom元素上。 // 如果元素都没有设置contenteditable="true",那么将作用于整个网页。 div.addEventListener("paste", function(e) { // 获取剪切板中的文本内容 console.log("e: 获取文本",e.clipboardData.getData("text")) }) // 点击div复制div中的内容到剪贴板 p.addEventListener("click", function() {clipboard(p.innerText)}) script> body> html>

paste测试获取普通文本.gif

到此就结束啦,如果就得学到啦,就给一个小小的star,谢您们~

注:本文转载自blog.csdn.net的飞鸟慕鱼的文章"https://blog.csdn.net/qq_34759481/article/details/83898710"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top