1. 搭建环境
环境变量:
sudo apt-get remove openjdk*
export JAVA_HOME=/opt/java/jdk1.8.0_211
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export NDK=/opt/java/android-ndk-r13b
export ANDROID_SDK=/opt/Sdk
export PATH=.:${JAVA_HOME}/bin:$PATH:$NDK:$ANDROID_SDK/platform-tools:$ANDROID_SDK/tools
export ANDROID_SDK=/opt/Sdk
export PATH=.:${JAVA_HOME}/bin:$PATH:$NDK:$ANDROID_SDK/platform-tools:$ANDROID_SDK/tools
export CC=/opt/java/android-ndk-r13b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
echo $CC #编译arm 下执行gcc
export CFCAGS="--sysroot=/opt/java/android-ndk-r13b/platforms/android-21/arch-arm"
#参数 指定编译头文件
$CC $CFCAGS -fPIC -shared -o libTest.so hello.c -I. # 生成 arm 平台下 的动态库libTest.so
2.1 新建android工程, Include C++ Support
2.2. 拷贝so 库到指定 目录 下 库名:libTest.so
2.3. native-lib.cpp 中 调用 so库函数
Java :
public native String stringFromJNI();
native-lib.cpp
#include <jni.h>
#include <string>
#include <android/log.h>
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "JNI", __VA_ARGS__)
// c++ 中调用 c ,必须 要 extern "C"
extern "C" {
extern jint test();
}
extern "C"
JNIEXPORT jstring
JNICALL
Java_dn_denganzhi_com_myapplication_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
jint r= test();
LOGE("hello ... jni--%d",r);
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
2.4. 修改 CMakeLists.txt指定编译的时候 链接 libTest.so 库
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.add_library( # Sets the name of the library.
native-lib# Sets the library as a shared library.
SHARED# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.find_library( # Sets the name of the path variable.
log-lib# Specifies the name of the NDK library that
# you want CMake to locate.
log )# 设置一个变量
# CMAKE_CXX_FLAGS c++的参数,会传递给编译器
# CMAKE_C_FLAGS c
# 编译的时候传递参数需要连接so
# 动态库生成可执行程序的时候链接:
# 3.gcc main.c -o main -I. -L. -lsy : 生成可执行程序
# -L 指定动态库的路径 libTest.so
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}")
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
# libTest.so 去掉 lib .so ,编译有2个库
target_link_libraries( # Specifies the target library.
native-lib
Test
# Links the target library to the log library
# included in the NDK.
${log-lib} )
2.5. gradle配置 abiFilters生成架构库
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "dn.denganzhi.com.myapplication"
minSdkVersion 15
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
abiFilters "armeabi-v7a"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
2.6. 加载库, 调用native方法运行
static {
System.loadLibrary("Test");
System.loadLibrary("native-lib");
}
注意:
在4.4以上,如果load一个动态库,需要先将这个动态库的依赖的其他动态库load进来
6.0以下, System.loadLibrary 不会自动为我们加载依赖的动态库
6.0以上,System.loadLibrary 会自动为我们加载依赖动态库
来源:CSDN
作者:小置同学
链接:https://blog.csdn.net/dreams_deng/article/details/104540775