Setting up an environment
环境变量:
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
----------------------- ndk13 -------------------------- -------------------------------------------------- --------------------------------
export CC = / opt / java / android-ndk-r13b / toolchains / arm-linux-androideabi-4.9 / prebuilt / linux-x86_64 / bin / arm-linux-androideabi-gcc
execute gcc under echo $ CC # compiler ARM
Export CFCAGS = "- sysroot = / opt / the Java / Android-ndk-r13b / Platforms / Android-21 / Arch-ARM"
# parameter specifies the precompiled header file
CC $ CFCAGS -fPIC -shared $ libTest.so hello.c -o the -I. # Generate dynamic library libTest.so arm under the platform
CC $ CFCAGS -c hello.c $ -o hello.o
Ar -crsv libStaticTest.a hello.o # generate static library libStaticTest.a
NDK 16 ------------------------------ ------------------ -------------------------------------------------- -----------------------------------
export CC = / opt / android- ndk-r16-beta1 / toolchains / arm-linux-androideabi-4.9 / prebuilt / linux-x86_64 / bin / arm-linux-androideabi-gcc
execute gcc under echo $ CC # compiler ARM
Export CFCAGS = "- sysroot = / opt / android-ndk-r16-beta1 / platforms / android-21 / arch-arm -isysroot / opt / android-ndk-r16-beta1 / sysroot -isystem / opt / android-ndk-r16 -beta1 / sysroot / usr / the include / ARM-Linux-androideabi "
# parameter specifies the compiled headers
$ CC $ CFCAGS -fPIC -shared -o libTestDynastic.so hello.c -I.
ndk 16 into the header android-ndk-r16-beta1 / sysroot separate directory under
----------------------------------------------------------------------------------------
--sysroot = XX
using xx as this one to find the directory compiled header files and libraries, look for the following default / usr / include usr / lib directory
--isysroot xx
header file search directory covering --sysroot, look XX / usr / include
-IXX
header file search directory
-LXX
specified library file directory
-xx.so
specify the name of the library you need to link
priority: -I> -isystem> sysroot
hello.c source file:
#include <stdio.h>
#include <stdlib.h>
int test(){
printf("test test ");
return 1000000;
}
int test2(){
printf("test2 test2 ");
return 1;
}
void main(){
test();
test2();
}
2.1 New android project, the Include C ++ Support
. 2.2 library copy so static library into the build environment to the specified directory under the library name: libTest.so, libStaticTest.a
2.3. Native-lib.cpp library function call so
Java :
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
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(); // 1000000, static test
extern jint test2(); // 1, dynastic test
}
extern "C"
JNIEXPORT jstring
JNICALL
Java_dn_denganzhi_com_myapplication_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
jint r= test();
LOGE(" test1---%d",r);
int r2= test2();
LOGE(" test2---%d",r2);
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
2.4. Editing CMakeLists.txt designated compile time link libTest.so library, compiled dynamic library , you can specify the red
# 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.
# 连接log
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 )Set a variable #
# parameters CMAKE_CXX_FLAGS c ++, and will be passed to the compiler
# CMAKE_C_FLAGS c
# compile time pass parameters need to connect SO
# dynamic library to produce an executable program when the link:
# -o main main.c 3.gcc the -I . -L -lsy:. generate executable
# -L libTestDynastic.so path specified dynamic library
set (CMAKE_CXX_FLAGS "$ {CMAKE_CXX_FLAGS} -L $ {CMAKE_SOURCE_DIR} / src / main / jniLibs / $ {ANDROID_ABI}")
# Specifies the Libraries CMake Should Link to your target Library. By You
# CAN Link Multiple the Libraries, SUCH AS the Libraries you the DEFINE in the this
# Build Script, prebuilt THIRD,-Party the Libraries, or System the Libraries.
# Representation to introduce static library way to introduce StaticTest
# add_library (StaticTest the STATIC iMPORTED)
# set target introducing path, here a line of
#set_target_properties (StaticTest PROPERTIES IMPORTED_LOCATION $ {CMAKE_SOURCE_DIR } / src / main / jniLibs / $ {ANDROID_ABI} /libStaticTest.a)# Cmake output message using the built-in variable
message ( "ANDROID_ABI: $ {ANDROID_ABI }")# The first parameter target SO
# compiler native-lib module requires StaticTest module
target_link_libraries (# Specifies target at The Library.
Native-lib
# # StaticTest static library compiler and linker
TestDynastic # compiler dynamic link library, dynamic library name is specified, go to the head lib tail SO
# Links The target Library to Library The log
# The included in the NDK.
$ {} log-lib)
2.5. Gradle configuration abiFilters generate Infrastructure Library
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. Load library, call the native method is running, the output
transfer:
package dn.denganzhi.com.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
// System.loadLibrary("Test");
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void showMsg(View view){
stringFromJNI();
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
Output:
Static library configuration:
# 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.
# 连接log
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 )Set a variable #
# parameters CMAKE_CXX_FLAGS c ++, and will be passed to the compiler
# CMAKE_C_FLAGS c
# compile time pass parameters need to connect SO
# dynamic library to produce an executable program when the link:
# -o main main.c 3.gcc the -I . -L -lsy:. generate executable
# -L libTestDynastic.so path specified dynamic library
#set (CMAKE_CXX_FLAGS "$ {CMAKE_CXX_FLAGS} -L $ {CMAKE_SOURCE_DIR} / src / main / jniLibs / $ {ANDROID_ABI}")
# Specifies the Libraries CMake Should Link to your target Library. By You
# CAN Link Multiple the Libraries, SUCH AS the Libraries you the DEFINE in the this
# Build Script, prebuilt THIRD,-Party the Libraries, or System the Libraries.
# Representation to introduce static library way to introduce StaticTest
add_library (StaticTest the STATIC iMPORTED)
# set target introducing path, here a line of
set_target_properties (StaticTest PROPERTIES IMPORTED_LOCATION $ {CMAKE_SOURCE_DIR } / src / main / jniLibs / $ {ANDROID_ABI} /libStaticTest.a)# Cmake output message using the built-in variable
message ( "ANDROID_ABI: $ {ANDROID_ABI }")# The first parameter target SO
# compiler native-lib module requires StaticTest module
target_link_libraries (# Specifies target at The Library.
Native-lib
StaticTest # static library compiler and linker
# TestDynastic # compiler dynamic link library, dynamic library name is specified, go to the head lib tail SO
# Links The target Library to Library The log
# The included in the NDK.
$ {} log-lib)
Run output:
Note:
In 4.4 above, if you load a dynamic library, we need to first load came in dependence of the dynamic library of other dynamic libraries
6.0 or less, System.loadLibrary does not automatically load-dependent dynamic library for our
more than 6.0, System.loadLibrary we will automatically load-dependent dynamic library