旧码整理内容。
一 build.gradle
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
android { compileSdkVersion 26 defaultConfig { externalNativeBuild { cmake { arguments '-DANDROID_STL=c++_static' // (1)编译c、cpp代码的参数 } } ndk { abiFilters "arm64-v8a" // (2)编译出的so支持的芯片架构 abiFilters "armeabi-v7a" } } sourceSets { main { jniLibs.srcDirs = ['src/main/cpp/dir_a/aaa/lib', 'src/main/cpp/dir_a/bbb/lib'] // 供c、cpp调用的so文件目录,下面是arm64-v8a这样的芯片目录,再内部才是so文件。 // 如果是直接供native类使用的则仅配置这一项即可,(1)(2)都可以省略。native类同下文。 } } externalNativeBuild { cmake { path 'src/main/cpp/CMakeLists.txt' // cmake入口 } } } |
二 c、cpp代码
在app\src\main目录下创建cpp目录。
1.CMakeLists.txt
根据build.gradle里 (3) 的配置,在cpp目录里创建CMakeLists.txt文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# 需要的一个ndk相关配置文件。这里默认和此CMakeLists.txt文件同一目录。非必须。 include(ndk-stl-config.cmake) # 执行编译的cmake的最小版本限制 cmake_minimum_required(VERSION 3.4.1) # c++源码文件根目录。可以有下一级目录。CMAKE_SOURCE_DIR指的是CMakeLists.txt所在目录 set(distribution_DIR ${CMAKE_SOURCE_DIR}/dir_a) # (==flag1 start==)下面是c++代码须要引用的资源。根据需要配置 # 定义一个静态资源名为“lib_aaa”,对应 ${CMAKE_SOURCE_DIR}/dir_a下的一个“aaa/lib”文件夹下的{芯片平台}目录下的a文件 add_library(lib_aaa STATIC IMPORTED) set_target_properties(lib_aaa PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/aaa/lib/${ANDROID_ABI}/libaaa.a) # 定义一个名为“lib_bbb"的资源,对应libbbb.so文件 add_library(lib_gperf SHARED IMPORTED) set_target_properties(lib_bbb PROPERTIES IMPORTED_LOCATION ${distribution_DIR}/bbb/lib/${ANDROID_ABI}/libbbb.so) # (==flag1 end==) # 设置编译参数,可以和build.gradle中的配置重复 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") # 我们开发的c++源代码文件。VigilesUtil即编译出的so库名称,文件名即libVigilesUtil.so # VigilesUtil.cpp文件默认和此CMakeLists.txt文件同一目录。 add_library(VigilesUtil SHARED VigilesUtil.cpp) # 指定VigilesUtil目标so,即VigilesUtil.cpp文件引用的h文件目录 target_include_directories(VigilesUtil PRIVATE ${distribution_DIR}/aaa/include ${distribution_DIR}/bbb/include) # 将目标so和须要用到的资源连接。android和log直接加入即可,lib_xxx即上面定义的资源 target_link_libraries(VigilesUtil android lib_aaa lib_bbb log) |
上面提到的ndk-stl-config.cmake文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
if(NOT ${ANDROID_STL} MATCHES "_shared") return() endif() function(configure_shared_stl lib_path so_base) message("Configuring STL ${so_base} for ${ANDROID_ABI}") configure_file( "${ANDROID_NDK}/sources/cxx-stl/${lib_path}/libs/${ANDROID_ABI}/lib${so_base}.so" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${so_base}.so" COPYONLY) endfunction() if("${ANDROID_STL}" STREQUAL "libstdc++") # The default minimal system C++ runtime library. elseif("${ANDROID_STL}" STREQUAL "gabi++_shared") # The GAbi++ runtime (shared). message(FATAL_ERROR "gabi++_shared was not configured by ndk-stl package") elseif("${ANDROID_STL}" STREQUAL "stlport_shared") # The STLport runtime (shared). configure_shared_stl("stlport" "stlport_shared") elseif("${ANDROID_STL}" STREQUAL "gnustl_shared") # The GNU STL (shared). configure_shared_stl("gnu-libstdc++/4.9" "gnustl_shared") elseif("${ANDROID_STL}" STREQUAL "c++_shared") # The LLVM libc++ runtime (static). configure_shared_stl("llvm-libc++" "c++_shared") else() message(FATAL_ERROR "STL configuration ANDROID_STL=${ANDROID_STL} is not supported") endif() |
2.VigilesUtil.cpp
和CMakeLists.txt文件一样,在cpp目录里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
#include <cstring> #include <jni.h> #include <cinttypes> #include <android/log.h> #include "dir_b/h_file_a.h" // 这个头文件在 \app\src\main\cpp\dir_a\aaa\include下的dir_b目录里 #include "dir_c/h_file_b.h" // 这个头文件在 \app\src\main\cpp\dir_a\bbb\include下的dir_c目录里 #define LOG_TAG "System.out" #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) static int arr[2]; static int var1; static const char *var2 = "VigilesUtil_app"; static void *func1(void *) { ssize_t rdsz; char buf[128]; while ((rdsz = read(pfd[0], buf, sizeof buf - 1)) > 0) { if (buf[rdsz - 1] == '\n') --rdsz; buf[rdsz] = 0; /* add null-terminator */ __android_log_write(ANDROID_LOG_DEBUG, tag, buf); } return 0; } int start_logger(const char *app_name) { tag = app_name; /* make stdout line-buffered and stderr unbuffered */ setvbuf(stdout, 0, _IOLBF, 0); setvbuf(stderr, 0, _IONBF, 0); /* create the pipe and redirect stdout and stderr */ pipe(pfd); dup2(pfd[1], 1); dup2(pfd[1], 2); /* spawn the logging thread */ if (pthread_create(&thr, 0, func1, 0) == -1) return -1; pthread_detach(thr); return 0; } extern "C" JNIEXPORT jlong JNICALL Java_com_cuiweiyou_util_VigilesUtil_callJNI (JNIEnv *jniEnv, jobject clazz, jstring str1, jstring str2, jstring str3) { jlong result; start_logger("jni-start---->"); string jstr1 = jniEnv->GetStringUTFChars(str1, NULL); string jstr2 = jniEnv->GetStringUTFChars(str2, NULL); string jstr3 = jniEnv->GetStringUTFChars(str3, NULL); // 方法体 LOGE("jni-end---->: %" PRIu64, result); return result; }; |
三 java的native类
以下代码没有什么特殊的了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package com.cuiweiyou.util; public class VigilesUtil { static { System.loadLibrary("VigilesUtil"); } public native long callJNI(String s1, String s2, String s3,); } |
使用:
1 2 3 4 |
VigilesUtil util = new VigilesUtil(); long r = util.callJNI("a", "b", "c"); |
end
声明
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/2267.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设