赞
踩
一、按照JNI的实现方式建一个工程
JNI的实现大概有以下几步:
最后建好的工程目录如下图所示
MyJni类是一个带native方法的java类
Navive.c是实现native方法的本地类
内容如下:
- #include <jni.h>
- #include <android/log.h>
-
- #ifndef _Included_com_jni_MyJni
- #define _Included_com_jni_MyJni
- #ifdef __cplusplus
- extern "C" {
- #endif
- /*
- * Class: com_jni_MyJni
- * Method: callNative
- * Signature: ()I
- */
- JNIEXPORT jint JNICALL Java_com_jni_MyJni_callNative
- (JNIEnv * env, jobject obj){
- __android_log_print(ANDROID_LOG_DEBUG,"Native.c","Hello! I am in native.\n");
- int i = 9;
- return (jint)i;
- }
-
- #ifdef __cplusplus
- }
- #endif
- #endif
仅打印了一句日志。
CMakeLists.txt的内容如下:
- cmake_minimum_required(VERSION 3.4.1)
-
- add_library(myso SHARED Native.c)
-
- set_target_properties(myso
- PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY
- "${CMAKE_CURRENT_SOURCE_DIR}/lib")
- include_directories(/usr/lib/jvm/java-8-oracle/include /usr/lib/jvm/java-8-oracle/include/linux)
-
- target_link_libraries(myso
- log)
添加了一个myso的动态库,输出到c目录下的lib目录中(实际输出的名字叫:libmyso.so)
至此,如果不需要交叉编译的话进入build目录下执行下面两条命令就可以生成so包了(目前build只是个空目录)
- $ cmake ..
-
- $ make
不过这个so包只能在当前pc上使用,不能用在手机上(实际上这个例子按上面的方法执行是会报错的,因为用到了android的日志,会找不到头文件的,这里只是说明一下本地编译与交叉编译的区别)。如果要交叉编译就要配置交叉编译环境,这就是今天的重头戏。
二、配置交叉编译环境
写一个脚本来记录这些参数,在build目录下新建configuer.sh文件,内容如下:
- /home/wxyz/Android/Sdk/cmake/3.10.2.4988404/bin/cmake \
- -DANDROID_ABI=armeabi-v7a \
- -DANDROID_PLATFORM=android-15 \
- -DCMAKE_BUILD_TYPE=Debug \
- -DANDROID_NDK=/home/wxyz/Android/Sdk/ndk-bundle \
- -DCMAKE_TOOLCHAIN_FILE=/home/wxyz/Android/Sdk/ndk-bundle/build/cmake/android.toolchain.cmake \
- -DANDROID_TOOLCHAIN=clang ..
这里对各个参数作个解释:
ANDROID_ABI 是cpu架构
ANDROID_PLATFORM是支持的最低android平台
ANDROID_NDK是ndk的根目录
CMAKE_TOOLCHAIN _FILE是工具链文件,这个参数非常重要,这里面还配置了很多其它参数。
ANDROID_TOOLCHAIN是C/C++编译器,可选Clang和gcc,官网推荐clang
最后还有两个点,代表上一级目录,即CMakeLists.txt所在的目录
在build目录下执行这个脚本,再执行make命令,可用于android的so包就出来了。
主要包含以下两个步骤:
一、编译独立工具链
编译独立工具链是利用$NDK/tools下的 make-standalone-toolchain.sh 脚本来生成独立的交叉编译工具链,先用 –help 参数来看一下具体用法
参数不多,有几个还是不再使用的,主要的只有以下几个:
好,现在来指定一下这几个参数,
然后运行这个脚本,稍等片刻就能看到如下的结果:
二、编译so包
新建一个jni工程,目录如下方式一
CMakeLists.txt中的内容就是重点了,这里面指定了刚刚编译好的独立工具链,内容如下:
- cmake_minimum_required(VERSION 3.4.1)
-
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
-
- # Android 5.0 以上需要在此处设置 PIE
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE")
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie")
-
- # 配置使用 NDK Standalone Toolchain 编译
- set(NDK_STANDALONE_TOOLCHAIN /tmp/ndk-hm/arm-linux-androideabi)
- set(CMAKE_SYSTEM_NAME Android)
- set(CMAKE_SYSTEM_VERSION 21)
- set(CMAKE_C_COMPILER ${NDK_STANDALONE_TOOLCHAIN}/bin/clang)
- set(CMAKE_CXX_COMPILER ${NDK_STANDALONE_TOOLCHAIN}/bin/clang++)
- set(CMAKE_FIND_ROOT_PATH ${NDK_STANDALONE_TOOLCHAIN})
-
- # 使用 NDK 提供的头文件
- add_definitions("--sysroot=${NDK_STANDALONE_TOOLCHAIN}/sysroot")
-
- add_library(myso SHARED CTest.c)
-
- set_target_properties(myso
- PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY
- "${CMAKE_CURRENT_SOURCE_DIR}/lib")
-
- include_directories(/home/hm/JDK/jdk1.8.0_151/include /home/hm/JDK/jdk1.8.0_151/include/linux)
-
- target_link_libraries(myso
- log)
进入build目录,执行一下:
- ~/cmake_sample/cross_for_android/build$ cmake ../c/
-
- ~/cmake_sample/cross_for_android/build$ make
进入c/lib目录看一下结果:
嗯,so包已经出来了,接下来建个工程验证一下,看看这个so包能不能用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。