仅作为个人学习记录,请当心求证。
developer.android.com/ndk/guides?…

前语

NDK即Native Development Kit,是Android上用来开发ckotlin面试题/c++的开发东西包。
装置过程:developer.android.com/studio/proj…

一、根底用法

  1. 在local.properties中配opengl版别过低怎样办备ndk目录:
ndk.dir=/Users/bc/android-ndk-r17c
sdk.dir=/Users/bc/Library/Android/sdk
  1. 新建cpp目录,编写native代码:

Android NDK开发根底
elementui运用教程间,cpelementui运用教程p文件是c+Java+代码文件,CMakeLists.txt是CMake构建脚本opengl形式(后边详细介绍)。
3. 在build.gradleopengl怎样装置与装备中装备ndk编译选项:

androidjvm是什么意思 {
defaultConfig {
ndk {
//elements 指定编译的abi架构
abiFilters "armeabi-v7a", "arm64-v8a"
}
externalNativeBuild {
// cmake装备
cmake {
//Sets optional flags for the C++ compiler.
cppFlags "-std=c++11 -frtti -fexceptions"
// Passes optional arguments to CMake.
arguments "-DANDROID_Sjvm调优面试题TL=c++_shared"OpenGL
argumentopengles3.1扩展包s "-DANDROID_TOOLCHAIN=gcc"
}
}
}
// Use this block to link Gradle to your CMake or ndk-build script
// 将gralde相关到cmake构建脚本
externalNjava模拟器ativeBuild {
cmake {
// 构建脚本途径
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
}
  1. 实施编译,Gradlelement翻译e会根据外部构建脚本CMakeLists.txt将c+kotlin和java+代码生成so,并打包到APK中,坐落/lib/{abi}/目录下。
  2. 在java代码中加载so:
public class NativeDemo {
private String libPath = "/data/datkotlin和java差异a/com.bc.sample/files/djvm优化ownload/nativeLib2.so";
public void initNativeLib() {
// 1.关于APK内的so文件,运用loelement是什么牌子adLibrarelementanimationy来加载
System.loadLibrary(kotlin和java"nativeLib");
// 2.关于文件系统中的so文件,运用load()来加载
System.load(libPath);
}
}

二、NDK编译根底

NDK支撑的编译办法有两种:
(1)CMake:NDK的默许构建东西,可在CMakeLists.txt 构建脚本中装备编译选项,CMake的C++作业时默许值为c++_static,CMaopengl怎样装置与装备ke和独立东西链默许启用C++异常,默许启用 RTTI。
(2)ndk-build:可在Android.mk 和 Applicakotlin言语tion.mk文件中装备编译选项,ndk-build的C++作业时默许值为none,ndk-build中默许停用C++异常,默许停用RTTI。

2.1 CMake根底

CMake官网介绍如下OpenGL,翻译过来便是,CMake是开源的、跨渠道的编译东西,能够根据所指定的编译环境生成对应的makefile文件JVM

CMake is an open-source, cross-platform family of tools
designed to belementanimationuild, testelementui and package software.
CMake is used to control the software compilation process
using skotlin和javaimple platform and compiler independent configuration
files, and generate native makefiles and workspaces that can
be used in the compiler environment of your ckotlin是什么意思hoijvm调优面试题ce.

CMake运用东西链来实施编译、链接等任务,对不同言语需求运用不同的东西链;
NDK的东西链文件坐落 NDK目录中的 {NDK_root}/build/cmake/android.toolchain.cmake 内,并能够在build.gradle中的android.defaultConfig.externalNativeBuild.cmake.arguments闭包下给CMake东西链传递参数。

2.1.1 CMake构建脚本

CMakeLists.jvm优化txt是CMake的构建脚本,在CMakeListselements.txt中能够运用cmaopengl版别过低怎样办ke的一些指令来自界说构建进程,elementary什么意思中文以下罗列了一些常用的cmake指令:

# Sets the minimum version of CMake rjava底子数据类型equired to build your native library.
#kotlin面试题 This ensures that a certain set of CMake features is availablkotlin现在不火了e to
# your build.jvm是什么意思
# cmake最低版别号
cmake_minimum_required(elementtypeVERSION 3.4.1)
# set:给变量赋opengles3.1扩展包
set(libkotlin是什么s "${CMAKE_SOURCE_DIR}/../jniLibs")
set(SOURCES src/main/cpp/native-lib.cpp src/main/cpp/native-lib2.java底子数据类型cpp)
# messagelementui运用教程e:打印信息
message("jniLibs folder: " ${libs})
# option:界说宏
option(JavaIS_jvm是什么意思ANDROjvm调优ID "编译ANDROID则界说为'ON',其他界说为'OFF'" ON)
# if-enopengles3.1扩展包dif:cmake的逻辑控制
if(IS_ANDROID)
message("Building for Android")
add_definitions(-DIS_ANDROID)
else()
message("Building for others")
endif(IS_ANDRjvm内存结构OID)
# include_directories:Add the givenjvm调优东西 directories to those tkotlin现在不火了he compiler uses to search for include files.把指定目录增加到编译器查找include头文件的elementary什么意思中文列表中
includjava底子数据类型e_directories(Tkotlin为什么盛行不起来hirdparty/opencv)
# find_library:This command is used to find a library.查找NDK库并将其途径存储为一个变量
find_library( # Sets theopengl怎样装置与装备 name of the path variable.
# 也能够直接用log,像下面的jnigraphics相同
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.kotlin面试题
log)
# Specifies a library name, specifies whetjvm内存结构her the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by addingelementui运用教程 mjvm调优东西ultiple add_library() commands,
# and CMjavaeeake builds them for you. When you builelementui运用教程d your app, Gradlekotlin是什么
# automatically packages shared libraries with your APK.
# add_javascriptlibrary:把一个library增加到工程
add_library( # Specifies the name of the ljvm原理ibrary.
native-lib
# Sets the librElementary as a shared library.
# 动态库用SHARED 静态库用STKotlinATIC
SHARED
# Provides ajvm内存结构 relative path tJavao your source file(s).
# 把全部需求用到的cpp都增加进来;或许用前面set的SOURCES变量
src/main/copengl版别过低怎样办pp/native-lelementtypeib.cpp
src/main/cpp/native-lib2.cpp)
# 增加一个已构建的库,运用IMPORTED
add_library(opencv_java3 SHARED IMPORTED)
# 对应已构建的库,需求指定库的途径
set_telementtypearget_properties(kotlin和javaopencv_java3
# Specifies the targjvm废物收回机制et library.
PROPERTIES IMPORTED_LOCATION
# Provides the path to the library you want to import.
"${libs}/${ANDROID_AJVMBI}kotlin为什么盛行不起来/libopencv_java3.so")
# target_link_libraopengl怎样装置与装备ries(<tarelementary什么意思中文get> ... <item>... ...) 相关target和item
# Lielementsnks your native library against one or more other natikotlin言语ve libraries.
# 首个参数是tjava编译器arget,后边kotlin和java差异的参数是item;target有必要先用add_library()创立过;
target_link_libraries( # Specifies tjvm原理he target library.
native-lib
opencv_java3
jnigraphics
${log-lib} )

2.1.2 gralde相关cmake

在build.gradle中装备cmake,即可将二者相关起来,相关后在java底子数据类型gralde构建的进程中就会构建native代码:

android {
defaultConfig {
ndk {
// 指定编译的abi架构
abiFilters "armeabi-v7a", "arm64-v8a"
}
externalNativeBuild {
// cmake装备
cmake {
//Sets optional flags for the C++ compiler.
cppFlags "-stdjvm内存模型=c++11 -frtti -fexceptions"
// Passes optional arguments to CMake toolopengl怎样晋级chain.
arguments "-DANDROIDjava底子数据类型_STL=c++_shared"
arguments "-DANDROID_TOOLCHAIN=gcc"
}
}
}
// Use this block to link Gradle to your CMakotlin和java差异ke or ndk-build script
// 将gralde相关到cmake构建脚本
externalNativeBuild {
cmake {
// 构建脚本途径
path "src/main/cpp/CMakeLists.txt"
verjvm内存结构sion "3.10.2"
}
}
}

2.1opengl怎样装置与装备.3 多个CelementtypeMake项目

假设项目中包含多个CMake项目,能够JVM运用一个 CMakeLists.txt 文件作为尖端 CMake 构建脚本,并增加其他 CMake 项目作为此构建脚本的依托项。
例如,项目中需求构建natjava言语ive-lib1和native-lib2两个so,则能够新建一个顶层 CMakeLists.txt,并将顶层 CMakeLists.txt装备到build.gralde中,然后在顶层 CMakeLists.txtkotlin是什么中增加native-lib1和naElementtive-lib2:

cmake_minimum_required(VERSION 3.4.1)
# add_subdirecjvm调优东西tory:将另一个 CMakeListsjvm调优东西.txt 文件指定为jvm废物收回机制构建依托项,然后相关其输出;
add_subdirectory(
# Specifies the directory of the CMakeLists.txt file.
./src/main/cpp/Kotlinnative-lib1
# Specifjava编译器ies the direcjvm内存结构tory for the build outputs.
./src/main/cpp/native-lib1jvm内存模型/outputs
)
add_subdirectory(
# Speckotlin是什么意思ifies the directory oelementary什么意思中文f the CMakeLists.txt file.
./src/main/ckotlin为什么盛行不起来pp/native-lib2
# Specifies the directory for the buijava编译器ld outpujvm是什么意思ts.
./java环境变量装备src/main/cpp/native-lib2/outputs
)

2.2 ndk-build根底

详细介绍见developer.android.com/ndk/guides/… (本文不要点介绍),elementanimation在build.gradle中装备如下:

externakotlin怎样读lNativeBuild {
ndkBuild {
path file('src/mjava言语ain/jni/Android.mk')
}
}

2.3 native api

在常用的cmake指令中介绍过,cmake能够运用find_library指令找到 NDK native api库并将其途径存储为一个变量;或许也能够在target_link_libraries直接运用NDK native api。

find_kotlin现在不火了liopengles3.1扩展包brary( # Sets the namejava面试题 of the path variable.
log-lib
# Speelementary什么意思中文cifies the name of the NDK library that
# you want CMakkotlin和java差异e to locate.
log)

下面首要罗列一些常用的NDK native api:

  • c库:<stdlib.h&gtopengl是什么意思; 和 <stdio.h> 等规范 C11 库头文件javascript;无需显示链接;
  • c++库:提OpenGL供 C++17 支撑;
  • log:<android/log.h&gjvm调优面试题t; 用于输出log到logcajvm废物收回机制t的API。从elementtypeAPI级别3初步提供;
  • bijvm调优面试题tmap:libjnigraphics 库用来访问 Java Bitmap 对象的像素缓冲区;
  • OpenGL ES 1.0 – 3.2:开放式图形库;
  • EGL:用于分配和办理 OpenGL ES 上下文和 Surface;
  • Vulkan:用于高性能三维图形烘托的低开支、跨渠道 Akotlin是什么PI。

更多NDK native api请参阅官方文档developer.android.com/ndk/referen… 。

三、NDK构建产品

native代码在构建后,有两种产品,生成哪一种产品是由编译装备决议的:
(1)native shared library动态库,即.so文件,CMakeelementtypeList.txt中装备如下:

add_kotlin是什么意思library(native-lib
SHARED
src/main/cpp/native-lib.cpp)

(2)native stkotlin面试题atic library静态库,即.a文件,CMakeList.txt中装备如下:

add_library(native-lib
STATIC
src/melementaryain/cpp/native-lib.cpp)

二者的差异:.so文件能够在作业进程中由java代码调Element用加载,.a文件不能在作业kotlin和java差异进程中直接由java代码加载;soopengles3.1扩展包文件在作业中能够去加载其他的so文件或许a文件;

四、JNI根底

JNI即java native interface,是java和native代码进jvm调优行交互的接口;

4.1 根底用法

在java中运用native关键字声明jni办法:

public class NativeDemo {
public native String stringFromJNI();
public static native void invole();
}

在kotlin中运用externl关键字声明jni办法:

class NativeDemo {
external fun stringFromJNI(): String;
}

有两种javaee办法能够完毕对应的native代码:
(1)静态注册
在cpp目录下,新建native_lib.cpp,增加对应的native完毕:

#include <jni.h>
#include <string>
// JNIEXPORT JNICALL、参数里的前两个参数JNIEnv*opengl烘托gpu怎样设置 env,jobject obj等是固定格式;固定参数中的java根底知识点jobject objjvm原理标明this
extern "C"
JNIEXPORT jstring JNICALL
Java_com_bc_sample_NativeDemo_stringFromJNI(
JNIEnv* ejvm调优东西nv,
jobject obj) {
std:kotlin现在不火了:string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str())opengl版别过低怎样办;
// static的native办法,参数默许是jclass
extern "C"
JNIEXPORT void JNICALL
Java_com_bc_sample_NativeDemo_stringFromJNI(
JNIEnv* env,
jclass clazz) {
}

(2)动态注册
在cpp目录下,新建native_JVMlib.cpp,在JNI_OnLoad时调Java用env->RegisterNatives进行注册(JNI_OnLoad是在动态库被加载时由系统JVM进行调用):

// 需求注册jni办法地址的类
static const char *jniClassName = "com/bc/sample/NativeDJVMemo";
// 需求注册的jni办法,分别标明java办法名、办法签名、native函数指针
// 办法签名能够用javap指令检查:
// javap -s /Users/bc/Demo/app/build/intermediates/javac/debug/classes/com/bc/sample/NativeDemo.classopengl怎样晋级
static JNINativeMethod methoopengles3.1扩展包ds[] = {{"stringFrojava怎样读mJNI", "()Ljava/lang/String", (jstring *) native_stringFromJNI}};
JNIEXPORT jint JNICALL JNI_elementaryOnLoad(JavaVM *vm,opengl怎样晋级 void *reservejvm调优东西d) {
JNIEnv *env = NOpenGLULL;
jint resultjava编译器 = -1;
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK)
return JNI_ERR;
if (!registerNatives(env))
return JNI_ERR;
result = JNI_VERSION_1_6;
return result;
}
static int rejvm内存模型gisterNatElementives(Jelement什么意思中文NIEnv *env) {
jclass clazz =elements env->FindClasKotlins(jniClassNaelement翻译me);
if (clazz == NULL)
return JNI_FALSE;
jint methodSize = sizeof(methods) / sizeof(mkotlin怎样读ethods[0]);
if (env->RegisterNatives(clazz, methods, methodSize) < 0)
return JNI_FALSE;
return JNI_TRUE;
}
// natijava编译器ve完毕
jstring native_stringFromJNI(JNIEnv *jvm优化env, joelement是什么牌子bject obkotlin是什么意思j) {
return env->NewStringUTF("hello");
}

4.1 JavaVM 和 JNIEnv

JNI 界说了两个关键数据结构“JavaVM”和“JNIEnv”,两者本质上都是指向函数表的二级指针。
Android中每个进程只允许有一个JavaVM。JNIEnv作用域为单个线程,可通过JavaVM的getEnv来获得其时线程的JNIEnKotlinv,JNIEnv可通过Gjvm是什么意思etJavaVM来获得JavaVM。

 // 保存JavaVM,方便在子线程中获取
static JavaVM *_my_jvm;
JNIEXPORT jint JNICALL JNI_OnLoelementsad(JavaVM *vm, void *reserved) {
env->GetJavaVM(&_my_jvm)
JNIEnv *opengles3.1扩展包env = NULL;
jint result = -1;
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_Ojvm调优面试题K)
return JNI_ERR;
return result;
}

4.2 线程与opengl怎样装置与装备JavaVM

在java代码中,能够通过Thread.start()发起一个线程;
关于opengl怎样晋级在native代码中通过pthread_create() 或 std::thread 发起的线程,是没有JNIEnv的,也就无法调用JNI,能够运用 AttachCurrentThread() 或 AKotlinttachCurrentThreadAsDaemon() 函数将JavaVM附加到线程,附加后的java环境变量装备线程能够调用JNI代码:

 // 保存JavaVM,方便在子线程中获取
static JavaVM *_my_jvm;
// 保存java层obj,方便在子线程获取OpenGL后回调作用
static java_obj;
JNIEXPORTkotlin怎样读 jint JNICALL JNI_Oopengl是什么意思nLoad(JavaVM *vm, void *reserved) {
env->GetJavajvm是什么意思VM(&_my_jvm)
JNIjvm调优Env *env = NULL;
jint resujvm调优面试题lt = -1;
if (vm->GetEnv((void **jvm是什么意思) &ampkotlin是什么;env, JNI_VERSION_1_6)java模拟器 != JNI_OK)
return JNI_ERR;
return result;
}
jstring native_stringFromJNI(JNIEnv *env, jobject obj) {
java_obj = ejvm废物收回机制nv->NewGlobalRef(obj);
}
void native_callback() {
JNIEnv *env = NULL;
_mjvm调优面试题y_jvm->AttachCurrentThread(&env, nullptr);
jmethodId method_call_back = env->GetMethodId(user_class, "caopengl三重缓冲llbackotlin言语k", "()V");
env->CallVoidMethod(java_obj, method_call_back);
/opengl形式/ 运用完后需求detach
_my_jvm->Dkotlin和javaetachCurrentThread();
}

4.3 JNI数据类java根底知识点

4.3.elements1 根底数据类型

/* jni.h源码 */
/* Primitkotlin面试题ive types that match up with Java equivaelementary什么意思中文lents. */
/* jni根底数据类型与java一一对应,二者可直接转化 */
typedef uint8_t  jboolean; /* unsignelementtypeed 8 bits */kotlin是什么
tyKotlinpedef int8_t   jbyte;    /* signed 8 bits */
typedef uint16_t jchar;    /* unsigned 16 bits */
typedopenglskiaef int16_t  jshort;   /* signed 16 bits */
typedef int32_t  jint;     /* signed 32 bits */
typedef int64_t  jlong;    /* signjvm废物收回机制ed 64 bits */
typedef float    jfloat;   /* 32-bit IEjava根底知识点EE 754 */
typedef double   jdouble;  /* 64-bit IEEE 754 */
/* "cardinal indices and sizes" */
typedef jint     jsize;
#opengl是什么意思ifdef __cplusplus
/*
* Refejvm内存模型relementaryence types, in C++
*/
class _jobject {};
class _jclassjvm废物收回机制 : public _jobject {};
class _jstring : public _jobject {};
class _jarray : public _jobject {};
class _jobjectArray : public _jarraykotlin和java {};
claopengl版别过低怎样办ss _jbooleanArray : public _jarray {};
class _jbyteArray : public _jarray {};
class _jcharArray : public _jarray {};
class _jjavaeeshortArray : public _jarray {};
class _jintArray : public _jarray {};
class _jljava怎样读ongArrajava环境变量装备y : public _jarray {};
clkotlin和javaass _jfloatArray : public _jarray {};
class _jdjavascriptoubleArray : public _jarray {};
class _jthrowable : pubjvm原理lic _jobjjava模拟器ect {};
typedef _jobject*       jobject;
typedef _jcljava怎样读ass*        jclass;
typedef _jstring*       jstring;elementanimation
typedef _jarray*        jarray;java底子数据类型
typedef _jobjectArray*  jobjectArray;
typedef _jbooleanArray* jbooleanArray;
typedef _jbyteAjvm优化rray*    jbyteArray;
typedef _jcharArray*    jchkotlin和javaarArray;
typedef _jshortArray*   jshortArray;
typedelementuief _jintArray*     jintArrayOpenGL;
typedef _jlongArray*    jlongArray;
typedef _jfloatArray*   jfloatArray;
typedef _jvm调优面试题jdoubleArray*  jdoubleelementanimationArrjvm调优参数ay;
typedef _jthrowKotlinable*    jthrowable;
typedef _jobject*       jweak;
#else /* not __cplusplus */
/*
* Refereopengl是什么意思nce types, ikotlin面试题n C.
*/
typedef voidopengles3.1扩展包*kotlin和java           jopengles3.1扩展包object;
tjvm调优参数ypedef jobject         jclass;
typedef jobject         jstring;
typedef jobject         jarray;
typedef jarray          jobjectArropengles3.1扩展包ay;
typedef jarray          jbooleanArray;
typedef jarray          jbyteArray;
typedef jarray          jcharArray;
typedef jarrayelementui          jshortArray;
typedef jarray          jintArray;
typedef jarray          jlongArray;
typedef jarray          jfloatArray;
typedef jarray          jdkotlin和javaoubleArray;
typedef jobject         jthrowable;
typedef jobjvm内存模型ject         jweak;
#endif /* not __cplusplus */

4.3.2 string类型

extern "C"
JNIEXPORT jstring JNICALL
Java_com_bc_sample_NativeDemoelementui_stringFromJNI(
JNIopengl烘托gpu怎样设置Env* env,
jobject obj, jstring str) {
jstring loacjava环境变量装备l_str = env->NewStringUTF("local_str");
const char * c  = env->GetStringUTFChars(str, false);
// 删去避免内存泄露
env->ReleaseStringUTFChars(str, c);
retkotlin和javaurn envkotlin和java差异->NewStringUTF(hello.c_str());
}

4.3.3 引证类型

例如:java中定kotlin为什么盛行不起来义了一个User类如下:

package com.bc.opengl怎样装置与装备sample;
class Userjvm调优参数 {
public String userName;
public static String TAG;
puelement是什么牌子blic void setName() {
}
public static void show() {
}
}

在jni中调用User相关element是什么牌子办法的办法如下:

extern "C"
JNIEXPopengles3.1扩展包ORT jobjjava底子数据类型ect JNICALL
Java_com_bc_sample_NativeDemo_objectFromJNI(
JNIEnv* env,
jobject obj, jobject user) {
jclass user_class = ekotlin怎样读nv->GetObjectClass(user);
// 1.java怎样读1 变量
jfieldID usjavascripter_name_id = env->GetFijava环境变量装备ledId(user_class, "userName", "Ljavajvm内存模型/lang/Strinelementsg");
jstring name = env->NewStringUTF("jack");
env->SetObjectFiled(user, user_name_id, name);
// 1.2 静态变量
env->Gejvm调优参数tStaticFieldID(user_class, "TAG", "Ljvm优化java/langjava怎样读/String");
/Java/ 2.1 办法
jmethokotlin怎样读dId method_selement是什么牌子et_name = env->GetMethodId(user_class, "setName", "()V");
env->CallVoidMethod(user, method_set_name);
// 2.2 静态办法
jmethodId metjvm调优东西hod_sjavaeehow = env-elements>GetStaticMethodId(user_class, "show", "()V");
env->CallStatjava模拟器icObjectMethod(user_class, method_show);
// 3 结构函数,用<init>标明
jclass usr_class = env->FindClass("com/bc/Javasample/User");
jmethodIdJava method_init = env->GetMethodId(user_class, "<init>", "()V");
jobject usr = env-&gjava底子数据类型t;NewObject(usr_class, method_init);
jobjectArray usr_array = env->NewObjectArray(5, usr_class, nullptr);
// 部分引证超越512会报错local reference table overflow (max=512);所以用完后要开释
env->DeleteLocalopengl怎样装置与装备Ref(user_class);
}

4.3.4 数组类型

不管是根底类型的数组jintArray、jelementuibooleanArray仍是引证类型的数组jobjectArray,都是承继了jarray,是一个引证类elementanimation型。

extern "C"
JNIEXPORT jobject JNIelementtypeCALL
Java_com_bc_sample_NativeDemo_objectFromJNI(
JNIEnv* env,
jobject obj, jintArray int_array,
jstringArray str_array,
jobjectArray user_array) {
int len = env->GetArrayopengl烘托gpu怎样设置Length(user_array);
// 1 底子数据类型数组
jint n = env->GetIntArrayElement(int_array, 0);
// 2 string数据类型数组
jstring str = static_cast<jstring>(env->GetObjectArrayElement(str_array, 0));
const char * c  = env->GetStringUTFChars(str, fkotlin怎样读alse);
env->ReleaseStringUTFChars(str, c);
// 3 引证类型数组;获得jobject后可按4OpenGL.3.3中获得user数据
jobjvm原理jecopengl烘托gpu怎样设置t user = env->GetObjectArrayElement(user_array, 0);
env->Djvm内存结构eleteLocalRef(user);
}

4.4 java签名

能够运用javap指令生成类的办法及参数签名:

>javapopengl是什么意思 -s java.lang.String

java类型及签名对应联系如下:

# 底子类型
V	 voielementanimationd	一般用于标明办法的回opengl和directx来值
Z	 belementary什么意思中文oolean
B	 byte
C	 char
S	 short
I	 int
J	 long
F	 float
D	 double
# 引证类型前要加L
String   Ljava/lang/Sopenglskiatring
Class    Ljaopengl烘托gpu怎样设置va/lang/Class
# 数组前要加[
ijvm调优nt[]    [I
Object[] [Ljava/lang/Object
# 办法签名:括号内标明参数,括号后标明回来类型(引证类型后要用;分隔)
String fun()                 () Ljava/lang/String;
int fun( int i, String str)   (ILjava/lajvm调优nopengl是什么意思g/String;)I

4.5 JNI全局引证 部分引证 弱引证

static javaopengl怎样装置与装备_obj;
jstring nativjvm调优东西e_stringFromJNI(JNIEnv *env, jobject obopengl形式j) {
// 部分引java怎样读
jclass str_clazz = env->FindClass("Ljava/lang/Stjavascriptring");
env->DeleteLocalRef(str_clazz);
// 全局引证,手动调用Deletkotlin怎样读eGKotlinlobalRef后才开释
java_obj = env->NewGlobalkotlin言语Reopengl烘托gpu怎样设置f(obj);
env->DeleteGlobalRef(objvm调优东西j);
// 弱引证,运用前需jvm调优求判别kotlin现在不火了是否为nuJVMljavaeel
java_obj =Kotlin envelementui->NewWeakGlobalRef(obj);
jboolean is_null = env->IsSamjava底子数据类型eObject(javajava模拟器_obj, nullptr);
}

4.6 JNI异常捕获

假定java中的ukotlin为什么盛行不起来ser类opengles3.1扩展包中界说如下

class User {
public void setName() throws RuntimeException {
}
public native void stringFromJNI();
}

在native层调用java代码产生异常时,可按如下办法捕获:

jstring native_stringFrokotlin现在不火了mJNI(JNIEnv *enjavascriptv, jobject obj) {
jclass uopengl是什么意思ser_class = env->GetObjectClass(user);
jmethodId method_set_namopenglskiae = env->GetMethodId(user_ckotlin为什么盛行不起来lass, "setName", "()V");
env->Cjvm优化allVoidMethod(user, method_set_name);
// 1.假设调用java办法setName时产生异常;可运用如下办法判别是否jvm是什么意思产生crash并捕获;否则会直接crash
jthrowakotlin现在不火了ble throwaelementanimationble_occurred = env->ExceptionOccurred();kotlin为什么盛行不起来
if (throwable_occurred) {element是什么牌子
env-&kotlin和java差异gt;ExceptionDescribe();
env->ExceptionClear();
}
// 2.或许当异常产生时,native层能够向javjvm内存模型a层抛出一个异常,在java层完毕try-catjvm优化ch
jclass throkotlin言语wable_clazz = env->FindClass("java/lang/RuntimeException");
env->ThrowNew(throwable_clazz, "excepjvm废物收回机制tion occurred");
}

4.7 JNIelementui线程

natJavaive开发常用的线程库:

  1. Posix API:<pthread.h>;
  2. c++11支撑的<topengl三重缓冲hreadkotlin言语.h>(本文不介绍);
#include<pthread.h>
// 线程互斥锁
pthread_mutex_t mutex;
// 线程条件变量
ptkotlin和java差异hread_cond_telement是什么牌子 cont;jvm调优东西
// 需求在子线程中element什么意思中文实施的办法
vkotlin和java差异oid *sayHello(voelementsid * arg) {
pthread_mutex_lockopenglskia(&mutjvm内存模型ex);
jstring local_arg = static_cast<jstring > (arg)opengles3.1扩展包;
LOG(local_arg);
pthread_mutex_unlock(&mutex);
return nullptr;
}
jstring native_stringFromJNI(JNIEnv *env, jobjkotlin为什么盛行不起来eckotlin言语t obj) {
// 1 创立线程
pthread_t handle;
jstring loacl_kotlin现在不火了str = env->NewStringUTF("local_str");
int result = pthreaopengl和directxd_create(&handle, nullptr, sajava怎样读yHello, loacl_str);
// 2 线程同步常用办法 
/opengl烘托gpu怎样设置/ pthread_mutex_lock() pthread_mutex_unlock()
pthread_mutex_ielementui运用教程nit(&mutex, nullptr);
pthread_mutex_destroy(&mutex);
// pthreajvm废物收回机制d_cond_wait() pthread_coopengles3.1扩展包nd_signal()
pthread_cond_init(&coelementary什么意思中文nd, nullptr);
pthread_cond_destroy(&ampelementary什么意思中文;cond);
}

五、ABI简介

不同的 Android 设备运用不同的 CPU,而elementui运用教程不同的 CPU 支撑不同jvm内存结构的指令集。CPU 与指令集的每种组合都有专属的运用二进制接口 (ABI)。CPU 与指令集的每种组合都有专属的使Java用二element是什么牌子进制接口 (ABjvm内存结构I)。
默许情况下,Gradle会针对全部非弃用ABI进行构建。要约束运用支撑的ABI集,能够在build.gradle中设置以下装备:

android {
defaultConfig {
ndk {
/jvm原理/ 约束编译的abi
abiFilters "armeabi",kotlin是什么意思 "arm64-v8a"
}
}
}

cpu架构及支撑的abi如下:

cpukotlin现在不火了 abi armeabi armeabi-v7a arm64-v8a x86 x86_64 mips mips64jvm内存结构
ARMv5 支撑
ARMv7 支撑 支撑
ARMv8 支撑kotlin为什么盛行不起来 支撑 支撑
x86 支撑 支撑 支撑
x86_64 支撑 支撑 支撑
MIPS 支撑
MIPS64 支撑 支撑

现在市场上干流CPU架java言语构是ARM v7;mips/mips64、xjavaee86 / x86_64市场占有率很少,能够忽略;java怎样读

六、crash仓库剖析

当native层产生crash时,crash仓库如下所示:

A/libc: Fatal signal 11 (SIGSEGV), code 1, fjava面试题ault addr 0x0 in tid 8427 (com.bc.sample), pid 8427 (cjvm调优om.bc.sample)
A/DEBUG: ***opengl是什么意思 *** *opengl是什么意思** *** *** *** ***elementui *** *** *** *** *** *** *** *** *opengles3.1扩展包**
A/DEBUG: Bujvm调优面试题ildkotlin是什么 fingerprint: 'Meizu/meizu_16th_CN/16th:8.1.0/OPM1.171019.026/1554749207:user/release-keys'
A/DEBUG: Revision: '0'
A/DEBUG:kotlin言语 ABI: 'arm64'
A/DEBUG: pid: 8427, tid: 8427, name: com.bc.sample  >>kotlin面试题> com.bc.sample <<<
A/DEBUG: sigkotlin和java差异nal 11 (SIGSEGV), code 1 (SEGV_MAPERR), faulelementanimationt addr 0xkotlin面试题0
A/DEBUG: Cause: null pointer dereference
A/Djvm内存模型EBUG:     x0   0000000000000000  x1   0000000000000000  x2   000000000000000e  x3   0000007feb6kotlin为什么盛行不起来0313f
A/DEBUG:     x4   0000000000000000  x5   0080000000000000  x6   7266opengl三重缓冲206f6c6c6548  x7   2b2b43206d6f7266
A/DEjvm调优参数BUG:     x8   0101010101010101  x9   406a834e06fb5ba3  x10  0000000000000000  x11  000000000000000e
A/DEBUG:     x12  0000000000000001  x13  0000000000000004  x14  00000074aa8bca40  x15  00000074a9b7ajavaee8a8
A/DEBUG:     x16  000000740b3bae98  x17  00000074a9aa189elementui0  x18  0000007425800080  x19  00000074256c2a00
A/DEBUG:     x20  0000007425288220  x21  00000074256c2a00  x22  0000007feb60340c  x23  000000740b68273a
A/DEBUG:     x24  0000000000000004  x25  00000074aa8bca40  x26  00000074256c2aa0  x27  0000000000000001
A/DEBUG:     x28  0000000000000002  x29  0000007feb603jvm内存模型070  xopengl怎样装置与装备30  000000740b3957f4
A/DEBUG:     sp   0000007feb603060  pc   00000074a9aa18a0  pstakotlin现在不火了te 0000000080000000
A/DEBUG: bjvm优化acopengl烘托gpu怎样设置ktrace:
A/DEBUG:     #00 pc 000000000001d8a0  /system/lib64/libc.so (strlen+16)
A/DEBUG:     #01 pc 000000000000f7f0  /data/app/com.bc.sample-2gV8CATI0EfKhLhzjuP6sA==/lib/arm64/libnative-lib.so (std::__ndk1::char_traits<char>::length(opengl怎样晋级char const*)+20)
A/DEBUG:     #02 pc 000000000000fdf8  /datajvm内存模型/app/cojavaeem.bc.sample-2gV8CATI0EfKhLhzjuP6sA==/lib/arm64/libnative-lib.so (std::__ndk1::basic_string<char, std::__ndk1::char_trajvm优化its<char>, std::__ndk1::allocator<char>>::assign(char const*)+44)
A/DEBUG:     #03 pc 000000000000f2f4  /data/appkotlin现在不火了/com.bc.sample-2gV8CATIjavaee0EfKhLhzjuP6sA==/lib/arm64/lijavascriptbnative-liopenglskiab.so
A/DEBjava面试题UG:     #04 pc 000000000000f1f8  /dajvm内存模型ta/app/com.bc.sample-2gV8CATI0EfKhLhzjuP6sA==/lib/arm64/likotlin现在不火了bnative-lib.so (Java_cokotlin和java差异m_bc_sample_Mopengl怎样装置与装备ainActivity_stringFromJNI+76)
A/DEBUG:     #05 pc 000000000000909c  /data/app/com.bc.sample-2gV8CATI0EfKhLhzjuP6sA==/oat/arm64/base.odex (offset 0x9000)

能够看到,crash信息描绘了产生crash的abi架构、crash的原因以及仓库bKotlinacktrace;
一般有两种办法可用来剖析native层crash的backtrace:

6.1 ndk-stack指令

ndk-stack指令坐落{NDK_roelementanimationot}/ndk-stack,运用时需求将crash的log复element什么意思中文制到一个txt文件中,这个指令会从txt中的

A/DEBUG: *** *** *** *** *** ***jvm优化 *** *** *** *** *** *** *** *** *** ***

后边初步剖析,运用办法如下:

# 用法:ndk-stack -sym ${SO_PARENTjvm废物收回机制_DIR} -dump crash_log.txt
# -sys so地址目录,即${SO_PARENT_DIR},留神有必要是目录名,不是so途径;
# -dump 产生craselement什么意思中文h的log信息,即crash_log.txt;

# 示例:
>ndk-stack -sym /Users/bc/demo/kotlin言语MyApplication2/app/build/intermediates/merged_native_libs/debug/out/lib/arm64-v8a -dump /Users/bc/crash.txt
# 作用如下:
********** Crash dump: **********
Build fingerprint: 'Meizu/meizu_16th_CN/jvm优化16th:8.1.0/OPM1.171019.026/1554749207:user/release-keys'
pid: 8427, tid: 8427, name: com.bc.sample  &gKotlint;>> com.bc.sample <<&ltelementanimation;
signal 11 (SIGSEGV), code 1java根底知识点 (SEGV_MAPelement是什么牌子ERR), fault addjavascriptr 0x0
Stack frame #00 pc 000000000001d8a0  /sjvm调优东西ystem/lib64/libc.so (strlen+16)
Sjava面试题tack frame #01 pcJava 000000000000f7f0  /data/app/com.bc.sample-2gV8CATI0EfKjvm内存结构hLhzjuP6sA==/lielementaryb/arm64/libnative-lib.so (std::__ndk1::char_traits&elementanimationlt;char>::length(char const*)+20): Routine std::_javascript_ndk1::cjavaeehar_trjvm调优aikotlin是什么意思ts<char&gtjvm调优面试题;::java底子数据类型lenopengl和directxgth(ckotlin面试题har conjava言语st*) at /Users/zhangbochen/Library/Android/sdk/ndjvm调优参数k/21.0.6113Element669/toolchaijava根底知识点ns/ljava环境变量装备lvm/prebuilt/darwin-x86_64/sysroot/usrjava底子数据类型/include/c++/v1/__string:217
Stack frame #02 pc 000000000000fdf8  /data/app/com.bc.sample-2gV8CATI0EfKhLhzjuP6sjvm调优面试题A==/lijava编译器b/arm64/libnopengl形式ative-kotlin为什么盛行不起来lib.so (std::__ndk1::basicjava模拟器_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char>>::assign(char const*)+44): Routine std:jvm优化:__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char>opengl三重缓冲 >::assign(char const*) at /Users/zhangbochen/Library/Android/sdk/ndk/21.0.6113669/toolchains/llvm/prebuiltjvm内存模型/darwin-x86_64/sysroot/uskotlin是什么意思r/includejvm调优东西/c++/v1/strjvm调优参数ing:2385
Stack frame #03 pc 000000000000f2f4  /data/kotlin面试题app/com.bc.sample-2gV8CATI0EfKhLhzjuP6sA==/lib/arm64/libnative-lib.so: Routinejvm调优 std::__ndk1::basic_striopengl怎样晋级ng<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >::operator=(char const*) at /Users/zhangbochen/Library/Android/sdk/ndk/21.0.6113669/toolchainjvm内存结构s/llvm/prebuilt/darwin-x86_64/sysroot/uselementui运用教程r/include/c++/v1/string:890
Stack frame #04 pc 000000000000f1f8  /data/ajvm废物收回机制pp/com.bc.saelementarymple-2gV8CATI0Ejvm内存模型fKhLhzjuP6sA==/lib/arm64/libnative-lib.so (Java_com_bc_kotlin面试题sample_MainActijava编译器vity_stringFromJNI+76):Java Routine Java_com_bc_sample_MainActivity_stringFromJNI at /Usersopengles3.1扩展包/zhangbochen/baidu/baiduapp-android-demo/MyApplication2/app/src/main/cpp/native-lib.cpp:9
Stack frame #05 pc 000000000000909javaeec  /data/app/com.bc.sample-2gV8CATI0EfKhLhzjuP6sA=kotlin为什么盛行不起来=/oat/arm64/base.odex (offset 0x9000)

6.2 addr2line指令

addr2line指令坐落{NDK_root}/toolchains/${ABI}/prebuilt/darwin-x86_64/bin/jvm原理x86_64-linux-andkotlin言语roid-addr2line,运用办法如下:

# 用法:arm-linux-androideabi-addr2line -C -f -e ${SOPATH}java根底知识点 ${Address}kotlin是什么意思
# -C -f 打印过错行数地址的函数称谓
# -e 打印过错地址的对应途径及行数
# ${SOPATH} so途径
# ${Address} crash仓库地址
# 示例如下:
>arm-linux-androidekotlin和javaabi-addr2line -C -f -e libnativeJava-lib.so 000000000000f1f8
# 作用如下,能够得到产生copengl三重缓冲rash的行号:
>Java_com_bc_sample_MainActkotlin是什么ivity_stringFkotlin面试题romJNI
/Userskotlin和java差异/bc/dopengles3.1扩展包emo/MyApplication2/app/src/main/cpp/native-lib.cpp:9

参阅文档:
cmake攻略:developer.android.com/ndk/guides/…
装备cmakejavaee:developer.android.com/studio/proj…
cmake指令文档:cmake.org/cmake/help/…
cmelement什么意思中文ake-toolchain文档:cmake.org/cmake/helementanimationelp/…
NDK native api简介:developer.android.com/nkotlin现在不火了dk/guides/…
NDK natiopengl怎样晋级ve api:developer.android.com/ndk/referen…
JNI 官方文档:docs.oracle.com/javase/7/do…