当前位置:   article > 正文

关于android studio使用cmake 编写jni调用静态库、动态库的方式_android studio编写jni库

android studio编写jni库

最近在帮助项目的大神测试编译出来的安卓动态库,需要用到jni,但是使用ndk去编译有太麻烦(还是懒),毕竟库太多了。然后以前听说android studio被谷歌搞得可以使用cmake

去编译源码库,于是乎,就更新了许久未用的android studio。在这个过程中真的是很恶心。使用jni动态注册函数时,总是注册不过,最后就是用android studio原声的

native-lib.cpp通过静态注册的方式搞定。

在CmakeList.txt文件中需要最一些配置更改。

这个是项目打开时原版本的CmakeList.txt在这个基础上加上自己所需要的静态库

  1. cmake_minimum_required(VERSION 3.4.1)
  2. #将静态库的头文件添加进来
  3. include_directories(
  4. ${CMAKE_SOURCE_DIR/src/main/include} #头文件多的话可以继续往下加
  5. ${CMAKE_SOURCE_DIR/src/main/include/..}
  6. ${CMAKE_SOURCE_DIR/src/main/include/...}
  7. 。。。。
  8. )
  9. add_library( # 自己的库名字
  10. native-lib
  11. # 将自己的库编译成动态库
  12. SHARED
  13. # 自己的cpp源码所在的路径即jni源码的路径
  14. src/main/cpp/native-lib.cpp )
  15. #添加自己所需的静态库 库多的话,可以使用下面的方式添加
  16. add_library( event #库名字 去掉了 lib 与 .a
  17. STATIC #必须的
  18. IMPORTED #必须的
  19. )
  20. set_target_properties(
  21. event
  22. PROPERTIES IMPORTED_LOCATION
  23. ${CMAKE_SOURCE_DIR}/libs/libevent.a #库在的路径,以cmakeList.txt所在的路径起
  24. )
  25. #添加自己所需的静态库 库多的话,可以使用下面的方式添加
  26. add_library( event #库名字 去掉了 lib 与 .a
  27. STATIC #必须的
  28. IMPORTED #必须的
  29. )
  30. set_target_properties(
  31. event
  32. PROPERTIES IMPORTED_LOCATION
  33. ${CMAKE_SOURCE_DIR}/libs/libevent.a #库在的路径,以cmakeList.txt所在的路径起
  34. )
  35. find_library( log-lib log ) target_link_libraries( native-lib #我自己的需要生成的动态库 event #将所需的库和自己要生成的动态库连接起来,多的话一次向下追加 x264 faac ${log-lib} )
  36. 在native-lib.cpp文件中写上的是关于自己的jni函数,将所需头文件包含进来,就可以通过jni函数调用静态库的函数。
  37. #include <jni.h>
  38. #include <string>
  39. #include <stdio.h>
  40. #include "ares.h"
  41. #include "faac.h"
  42. #include "uuid.h"
  43. #include "turbojpeg.h"
  44. #include "x264.h"
  45. void insertSort(int *data,int len);
  46. //调用libcares的例子
  47. extern "C"
  48. JNIEXPORT jint JNICALL Java_com_skylight_testlibs_JNIHeader_AreasLibInit(JNIEnv *env, jobject )
  49. {
  50. jint result=ares_library_init(1);
  51. return result;
  52. }
  53. //调用libuuid的例子
  54. extern "C"
  55. JNIEXPORT jint JNICALL Java_com_skylight_testlibs_JNIHeader_UuidIsNull(JNIEnv *env, jobject)
  56. {
  57. const uuid_t uu= {0};
  58. jint result=uuid_is_null(uu);
  59. return result;
  60. }
  61. //调用libturbojpeg的例子
  62. extern "C"
  63. JNIEXPORT jint JNICALL Java_com_skylight_testlibs_JNIHeader_TJAlloc(JNIEnv *env, jobject )
  64. {
  65. unsigned char* c= tjAlloc(128);
  66. const char* result=(const char*)c;
  67. if (c == NULL)
  68. {
  69. return -1;
  70. } else{
  71. return 0;
  72. }
  73. }
  74. //调用libx264库的例子
  75. extern "C"
  76. JNIEXPORT jint JNICALL Java_com_skylight_testlibs_JNIHeader_X264PictureAlloc(JNIEnv *env, jobject )
  77. {
  78. x264_picture_t *ipic= nullptr;
  79. x264_picture_init( ipic );
  80. jint result= x264_picture_alloc( ipic, 32, 512, 256 );
  81. return result;
  82. }
  83. //调用faac库的函数例子
  84. extern "C"
  85. JNIEXPORT jint JNICALL Java_com_skylight_testlibs_JNIHeader_FaacEncClose(JNIEnv *env, jobject )
  86. {
  87. jint result=-2;
  88. unsigned long nSampleRate = 44100;
  89. unsigned int nChannels = 2;
  90. unsigned int nPCMBitSize = 16;
  91. unsigned long nInputSamples = 0;
  92. unsigned long nMaxOutputBytes = 0;
  93. faacEncHandle hEncoder = {0};
  94. faacEncHandle handle= faacEncOpen(nSampleRate, nChannels, &nInputSamples, &nMaxOutputBytes);
  95. if (handle == NULL)
  96. {
  97. result= -1;
  98. } else{
  99. result= 0;
  100. }
  101. return result;
  102. }
  103. //调用insertSort函数
  104. extern "C"
  105. JNIEXPORT void JNICALL Java_com_skylight_testlibs_JNIHeader_insertSortArray(JNIEnv *env, jobject obj,jintArray array)
  106. {
  107. jint *data=env->GetIntArrayElements(array,NULL);
  108. jsize len=env->GetArrayLength(array);
  109. insertSort(data,len);
  110. env->ReleaseIntArrayElements(array,data,0);
  111. }
  112. //排序
  113. void insertSort(int *data,int len)
  114. {
  115. int temp = 0;
  116. int i = 1;
  117. int j = 0;
  118. for (; i < len; i++)
  119. {
  120. temp = data[i];
  121. j = (i - 1);
  122. for (; j >= 0; j--)
  123. {
  124. if (data[j] > temp)
  125. {
  126. data[j + 1] = data[j];
  127. }
  128. else
  129. {
  130. break;
  131. }
  132. }
  133. data[j + 1] = temp;
  134. }
  135. }
  136. 在java层的代码就很简单了直接写上native方法就行可以了。
  137. public class JNIHeader
  138. {
  139. static {
  140. System.loadLibrary("native-lib");
  141. }
  142. public native void insertSortArray(int[] data);
  143. public native int AreasLibInit();
  144. public native int UuidIsNull();
  145. public native int TJAlloc();
  146. public native int X264PictureAlloc();
  147. public native int FaacEncClose();
  148. }
  149. 在build.gradle中还需要加入以下配置,在defaultConfig中加入下面的配置,
  150. externalNativeBuild {
  151. cmake {
  152. arguments '-DANDROID_PLATFORM=android-23',
  153. '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static'
  154. }
  155. }
  156. ndk {
  157. abiFilters 'armeabi-v7a' // armeabi-v7a 这里需要过滤一下处理器类型
  158. }
  159. 在defaultConfig的下面加入这个配置
  160. sourceSets {
  161. main {
  162. jniLibs.srcDirs = ['libs']
  163. }
  164. }
  165. 这样就可以使用cmake在android studio中调用静态库的函数了


  1. android studio在调用动态库时和调用静态库的方式略有不同,不知道别人是
  2. 怎么解决的,目前我的android studio碰到调用动态库的问题如下:
  3. 1、在src/main/目录下新建一个文件夹jniLibs,在该文件夹中需要建立区分ABI的类型的文件夹
  4. -->即armeabi-v7a armeabi-arm 等子文件夹,最终的目录会是
  5. ------>src
  6. ---------->main
  7. --------------->jniLibs
  8. ----------------------->armeabi-v7a(armeabi-arm)等
  9. 路径会是--->src/main/jniLibs/armeabi-v7a 或者对应的ABI
  10. 2、将自己所要调用的动态库.so文件放置在上述目录中 例如(src/main/jniLibs/armeabi-v7a/xxxx.so)
  11. 3、在CmakeList.txt文件中添加动态库
  12. add_library( 库名 SHARED IMPORTED )
  13. set_target_properties( 库名 PROPERTIES
  14. IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/lib库名.so )
  15. 注:ANDROID_ABI就是ABI类型--->armeabi-v7a或者对应的
  16. 4、在java代码中加载动态库
  17. System.loadLibrary("库名");
  18. 建议:将调用的动态库放在native-lib库的上面。先加载三方动态库
  19. 5、在target_link_libraries()中将动态库添加进去


最近在帮助项目的大神测试编译出来的安卓动态库,需要用到jni,但是使用ndk去编译有太麻烦(还是懒),毕竟库太多了。然后以前听说android studio被谷歌搞得可以使用cmake

去编译源码库,于是乎,就更新了许久未用的android studio。在这个过程中真的是很恶心。使用jni动态注册函数时,总是注册不过,最后就是用android studio原声的

native-lib.cpp通过静态注册的方式搞定。

在CmakeList.txt文件中需要最一些配置更改。

这个是项目打开时原版本的CmakeList.txt在这个基础上加上自己所需要的静态库


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/742809
推荐阅读
相关标签
  

闽ICP备14008679号