Android Studio 2.2.2 NDK 之 坑


0 .Thanks

  • 郭大神(公司的超级大神)
  • AndroidStudio2.2下利用CMake编译方式的NDK opencv开发
  • cannot use ‘throw’ with exceptions disabled
  • Android开发实践:如何设置NDK的编译选项
  • Android Studio 2.2 NDK CMake方式入门
  • 在 Android Studio 2.2 中愉快地使用 C/C++

1 .配置

  • Android Studio 2.2.2 以上
  • 下载好NDK,SDK manager 中下载好。
  • 新建工程,把C++ Include 勾选。
  • 新建好之后,我们不用像以前那样去配置MK文件,以前的配置,现在都转移到了CMakeLists.txt和Gradle中。

2 .坑


  • 1 . 添加您写的CPP和头文件
    在CMakeLists.txt中添加:
add_library( # Sets the name of the library.
             SoundTouchUtils

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             # Associated headers in the same location as their source
             # file are automatically included.
             src/main/cpp/native-lib.cpp
             src/main/cpp/ST_Cpp/cpu_detect_x86.cpp
             #在这里换行添加您的cpp文件,每一个都要写!#
              )

为了避免找不到头文件,建议在cpp目录下新建一个专门存放头文件的目录:
在CMakeLists.txt中添加:

# Specifies a path to native header files.
include_directories(src/main/cpp/ST_H)

  • 2 .链接到您的库文件

一般,C++和Java的交互,我们是写一个文件,例如

#include 
#include 
extern "C"
jstring Java_ndktest_chestnut_huiyu_com_ndktest_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

如上,通过这个文件,我们java就能通过这个文件中所声明的接口,去调用C++里面的函数。
然后,在此之前我们要在Java里面load我们的so库:

// Load the native library upon startup
    static
    {
        System.loadLibrary("SoundTouchUtils");
    }

这里,load的名称:SoundTouchUtils必须
和上面的文件名称一样
必须在CMakeList.txt中声明:

target_link_libraries( # Specifies the target library.
                       SoundTouchUtils
                       #这里写下你的库文件名称#
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

  • 3 .注意C++文件的编译指令
    在C++中,某些算法或者运算为了加速或者其他的目的,使用了某些特定平台上的运算指令,如MMX?,
    而Android Studio默认是全平台编译的,所以,其他平台特有的指令,会导致在一些平台上找不到。
    解决:
  • 仔细查看报错信息,找到这些指令调用的地方,然后去重写一个其他平台能用的指令。
  • 如果,程序只是跑在某些特定的平台上,你可以指定编译的平台。
    在app-build.gradle中:android节点- defaultConfig - externalNativeBuild
externalNativeBuild {
            cmake {
                abiFilters 'armeabi', 'armeabi-v7a', 'arm64-v8a'
            }
        }

  • 4 .开启C++的标准异常
    默认的情况下,Android Studio中是没有开启C++的标准异常,
    所以,会导致一下编译报错:
    cannot use ‘throw’ with exceptions disabled
    解决:在app-build.gradle中:android节点- defaultConfig - externalNativeBuild
externalNativeBuild {
            cmake {
                cppFlags "-fexceptions"
            }
        }

  • 5 .从Eclipse中移植的JNI项目
    如果您直接复制粘贴,当你编译的时候,会发现报错了,有一些在库中定义的方法找不到
    因为,新的Android Studio编译所规范的方法命名规则已经不同于以前的Eclipse,所以,
  • 你要把方法名称改正确(照着报错信息改)
  • 改变方法命名规则:(暂时不清楚怎么改,知道的孩童请说一下)

你可能感兴趣的:(Android Studio 2.2.2 NDK 之 坑)