美文网首页
Android C++开发

Android C++开发

作者: hjm1fb | 来源:发表于2018-07-18 11:51 被阅读100次

语法

JNI数据类型描述符语法定义
JNI方法声明

当声明的是static方法时,传入Native的是Java类对应的jClass对象,当声明的是非static方法时,传入的是java对象对应的jObject对象

native接口和java回调方法都得同时为static和非static(修正此文: native方法为非static时,也可以回调Java的static方法,就像java的对象也可以调用自身的static方法)

在异步线程获取JNI环境env
weak Global Reference等三种引用

JNI修改Native方法数组参数中数组里面的元素值(如果是调用GetIntArrayElements,需要在之后调用ReleaseIntArrayElements来释放数组)

CMake

link_directories, LINK_LIBRARIES, target_link_libraries使用总结
A list of common CMake antipatterns
通过CMake 实现宏定义define
cmake教程5-macro宏定义以及传递参数给源文件
CMake----if与option使用小记
配置ConfigFile
equal用法
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DSHOWLOG")和
add_definitions(-DSHOWLOG)的区别:
add_definitions还可以这样写:
add_definitions(-DSHOWLOG = "showLog")

GLOB的用法example和tip 摘自:
CMAKE AND VISUAL STUDIO
cmake使用教程(十)-关于file
cmake的使用笔记

# Collect sources into the variable MATH_SOURCES without
# having to explicitly list each header and source file.
#
# CMake documentation states "We do not recommend using GLOB to collect a
# list of source files from your source tree. If no CMakeLists.txt file
# changes when a source is added or removed then the generated build system
# cannot know when to ask CMake to regenerate". 
#其实CMakeList文件里加个空格就算修改 也会重新编译了
file (GLOB MATH_SOURCES
      "*.h")

# Collect sources into the variable SIMPLE_FUNCTION_SOURCES
file (GLOB SIMPLE_FUNCTION_SOURCES
      "simple/*.h"
      "simple/*.cxx")

# The recommended way to collect sources in variable 
# ADVANCED_FUNCTION_SOURCES by explicitly specifying the source files
set  (ADVANCED_FUNCTION_SOURCES
      "advanced/AdvancedFunctions.h"
      "advanced/AdvancedFunctions.cxx")


#*.cxx      - 匹配所有的cxx结尾的文件
#*.vt?      - 匹配所有的vta,...,vtz等文件
#f[3-5].txt - 匹配f3.txt, f4.txt, f5.txt这三个文件
#GLOB_RECURSE 与GLOB类似,区别在于它会遍历匹配目录的所有文件以及子目录下面的文件
set(CUR ${CMAKE_CURRENT_SOURCE_DIR})
file(GLOB_RECURSE files FOLLOW_SYMLINKS LIST_DIRECTORIES true RELATIVE ${CUR}/.. *)
foreach(file IN LISTS files)
    message(STATUS ${file})
endforeach(file)
link_directories与sourceSets的区别

我们在CMakeLists里设置link_directories是为了能够在编译时找到相应的库.
如果依赖的是.a文件,就会一起打包到最终的so文件里;

如果依赖的是so文件,就不会被打包到最终的so文件里,
也不会被打包到APK.
但是我们需要将依赖的so文件打包到APK里,不然的话运行APP加载C++库时会Crash,
方法就是将依赖的so文件放到Android Studio默认的jniLibs路径下app/src/main/jniLibs/
或者通过sourceSets自定义路径:

sourceSets {
        main {
            jniLibs.srcDir  yourJniLibsPath
         }
 }
cppFlags与CMAKE_CXX_FLAGS
// CMakeLists.txt
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fopenmp")

这里的CMAKE_CXX_FLAGS包含了Gradle里设置的cppFlags变量,相当于是叠加的关系,因此,这几个flag写在Gradle的cppFlags或者CMakeLists.txt文件的CMAKE_CXX_FLAGS里都可以

NDK build

ndk-build + Android.mk + Application.mk编译JNI,及JNI HelloWorld篇

调试Tip

Android NDK开发Crash错误定位

打印jobject的class name

log打印格式
bool值可以用%d打印,例如:

bool ok = true;
bool notOk = false;
LOGD(TAG, "ok = %d %d", ok, notOk);
// 输出: ok = 1 0

异常处理

Android JNI 调用时的异常处理

文件操作

新建文件等文件操作示例

依赖第三方so文件

使用cmake连接第三方so

引入第三方so库

Android开发中libs目录下so文件的正确放置“姿势
android 匹配so文件规则
关于Android的.so文件你所需要知道的

其他tip

编译so 文件时, CMake默认的编译选项在 ndkDir/build/cmake/android.toolchain.cmake' 里设置.

打开文件,在Generic flags下可以发现, 默认的build 使用了-g 也就是使用debug模式, 如果不需要这个,可以在这行前面加#注释掉.

gradle的abiFilters配置有bug,如果APP module和子module的配置不一样的话,会出现C代码更改不生效以及so文件无法打包进APK的bug, 所以需要APP module和子module的abiFilters配置是一样的

相关文章

网友评论

      本文标题:Android C++开发

      本文链接:https://www.haomeiwen.com/subject/zrlopftx.html