Android JNI for "Android Studio 2.2 or higher"

点击浏览 官网说明 (要翻墙)


安装插件

需要打开SDK Manager

菜单栏 Tools>Android>SDK Manager

点击切换到 SDK Tools 选项卡

勾选 LLDB、CMake、NDK 进行安装       如下图


当安装后,会在sdk目录下多出三个目录:cmake、lldb、ndk-bundle


建立支持c/c++的工程

新建工程时,勾选『include C++ Support』如下图


然后进行正常的向导选择,当进行到尾页出现:


上面下拉列表选择c++标准,下面复选框分别表示,是否需要支持异常处理机制 及 运行时类型识别(RTTI)

然后点击Finish 生成工程


下图是默认标准生成的工程,自动新增了一个cpp目录及目录下的默认.cpp文件

      并在app/ 下新增了一个 CMakeLists.txt 文件,放入group-> External Build Files

      在build.gradle中, defaultConfig配置下 添加了一个名为 externalNativeBuild配置



下图是使用c++11标准,并勾选了两个support选项后的工程视图:

与上图的区别是  在externalNativeBuild配置下的 cppFlags 赋值了



生成的文件与工程

当在创建工程时,选择创建一个默认Activity时,会生成一段简单的c++函数在native-lib.cpp文件中,

名为stringFromJNI()。  

构建脚本在CMakeLists.txt中:

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 it 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).
             # Associated headers in the same location as their source
             # file are automatically included.
             src/main/cpp/native-lib.cpp )

# Searches for a specified prebuilt library and stores the path as a
# variable. Because system libraries are included 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 )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in the
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )
里面配置了库的名字、源文件位置、添加log-lib、链接lib等
运行后,生成的so文件在 <project-path>/app/build/ intermediates/ cmake/debug/obj/ 下


如果想分析apk文件:Build>Analyze然后会弹出一个选择文件对话框,默认选择当前工程的apk,

当然也可以选择其他apk,选定后如下图:



将C / C ++代码添加到现有项目

1. 创建新的本地源文件,并添加到项目中。如果已经有本地代码或要导入预建的本地库,可以跳过这一步

2. 创建CMake的构建脚本。如果你已经有一个现有的本地库及CMakeLists.txt构建脚本,或者使用ndk-build,

并包括一个Android.mk的构建脚本,你可以跳过这一步

3. Gradle与提供了CMake或ndk-build脚本的本地库进行关联。Gradle使用构建脚本导入源代码到studio项目,

并将要地库(so文件)打包进apk中


创建新的本地源文件

创建cpp目录与源文件,步骤如下:

>在moudle>src>main 右键new 一个目录,比如名为cpp

>在目录上右键new c/c++ Source file,可以勾选同时创建头文件


创建CMake的构建脚本

> 该脚本必须是一个纯文本文件,且命名为CMakeLists.txt

> 可以创建在项目中的任何位置,脚本中的源文件、本地库的路径是相对于当前构建文件的

> 脚本命令 :

#最小需要的cmake版本
cmake_minimum_required(VERSION 3.4.1)
add_library(
#定义库的名字
native-lib 
#声明为共享库
SHARED
#源文件路径
src/main/cpp/native-lib.cpp
#为了让CMake定位到头文件,可以指定头文件的目录
include_directories(src/main/cpp/include/)
)

可以使用多个add_library()命令:添加其它一些源文件,定义额外的库供CMake脚本来构建

>生成的so库名为:lib[库名].so,如上配置即生成:libnative-lib.so

在java代码中加载这个库时,只需要使用CMake中定义的库名:

static {
    System.loadLibrary(“native-lib”);
}

注:如果从CMake构建脚本中重命名或移除了一个库,那就需要清理一个工程:Build>Clean Project


添加 NDK APIs

安卓NDK提供了一些有用的native APIs,可以在CMakeLists.txt进行添加

find_library()命令,来定位一个NDK库,并存储它的路径到一个变量中。

下面的例子演示了 定位Android-specific log support library (点击该串英文跳转到 安卓每个Api Level所对应新增支持的NDK libs

页面,类似LOCAL_LDLIBS := -lGLESv1_CM    即表示库名为GLESv1_CM;

而log库是  LOCAL_LDLIBS := -llog

),

将其路径添加到变量log-lib中

find_library( # Defines the name of the path variable that stores the
              # location of the NDK library.
              log-lib

              # Specifies the name of the NDK library that
              # CMake needs to locate.
              log )

> target_link_libraries()命令,为了在本地库使用NDK库,需要使用该命令进行链接

find_library(...)

# Links your native library against one or more other native libraries.
target_link_libraries( # Specifies the target library.
                       native-lib

                       # Links the log library to the target library.
                       ${log-lib} )

> 添加NDK源文件到本地库。比如NDK的路径保存在环境变量ANDROID_NDK中:

使用add_library命令添加源文件,并使用target_link_libraries命令进行链接

add_library( app-glue
             STATIC
             ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c )

# You need to link static libraries against your shared native library.
target_link_libraries( native-lib app-glue ${log-lib} )

添加其他预编译库

> 由于预编译库已经构建好了,你只需要引入即可,如下引入一个名为imported-lib 的库,使用了IMPORTED标识:

add_library( imported-lib
             SHARED
             IMPORTED )

> set_target_properties命令 指定库的路径

一些库,在不同的cpu架构上,生成了针对性的so库文件。

可以使用环境变量ANDROID_ABI ,它使用一个NDK支持的默认ABI列表,

也可以使用gradle里手动配置的abi过滤列表中的项(关于配置列表见下文:gradle中指定ABIs)

add_library(...)
set_target_properties( # Specifies the target library.
                       imported-lib

                       # Specifies the parameter you want to define.
                       PROPERTIES IMPORTED_LOCATION

                       # Provides the path to the library you want to import.
                       imported-lib/src/${ANDROID_ABI}/libimported-lib.so )


> include_directories命令 指定头文件位置

同样为了在编译时找到头文件,可以使用

include_directories( imported-lib/include/ )
注:当你想打包一个预编译库,且它不需要在构建时被你的库所依赖,那么即使它依赖了imported-lib库,也不需要执行以下的链接命令


target_link_libraries命令,链接预编译库和本地库

target_link_libraries( native-lib imported-lib app-glue ${log-lib} )

Gradle关联本地库

界面操作

在一个新的moudle中,右键moudle-name,点击『Link C++ Project with Gradle』


选择构建系统是Cmake还是ndk-build,然后选择对应的某一本库的构建文件

Cmake 对应CMakeLists.txt

ndk-build 对应Android.mk

点击ok

在moudle下的build.gradle中添加externalNativeBuild{}   (studio2.2后会自动生成)

android {
  ...
  defaultConfig {...}
  buildTypes {...}

  // Encapsulates your external native build configurations.
  externalNativeBuild {

    // Encapsulates your CMake build configurations.
    cmake {

      // Provides a relative path to your CMake build script.
      path "CMakeLists.txt"
    }
  }
}
这里添加的是Cmake脚本,如果是nkd-build脚本

externalNativeBuild {
   ndkBuild{
      path "Android.mk"
   }
}

指定可选配置

可以在module级的build.gradle中defaultConfig{}下添加externalNativeBuild{}的可选配置

当然也可以添加在某一个或多个 product flavor (即渠道)中

比如,使用了CMake或ndk-build构建的工程中,定义了多个本地库,而在product flavor只使用一个库,

   可以使用targets属性来配置:

android {
  ...
  defaultConfig {
    ...
    // This block is different from the one you use to link Gradle
    // to your CMake or ndk-build script.
    externalNativeBuild {

      // For ndk-build, instead use ndkBuild {}
      cmake {

        // Passes optional arguments to CMake.
        arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"

        // Sets optional flags for the C compiler.
        cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2"

        // Sets a flag to enable format macro constants for the C++ compiler.
        cppFlags "-D__STDC_FORMAT_MACROS"
      }
    }
  }

  buildTypes {...}

  productFlavors {
    ...
    demo {
      ...
      externalNativeBuild {
        cmake {
          ...
          // Specifies which native libraries to build and package for this
          // product flavor. If you don't configure this property, Gradle
          // builds and packages all shared object libraries that you define
          // in your CMake or ndk-build project.
          targets "native-lib-demo"
        }
      }
    }

    paid {
      ...
      externalNativeBuild {
        cmake {
          ...
          targets "native-lib-paid"
        }
      }
    }
  }

  // Use this block to link Gradle to your CMake or ndk-build script.
  externalNativeBuild {
    cmake {...}
    // or ndkBuild {...}
  }
}

注:要学习配置product flavors和构建变量,请转向ABIs the NDK supports

       要学习配置Cmake变量,请转向Using CMake Variables


指定ABIs

默认情况下,生成的.so文件含ABIs the NDK supports 所支持的所有ABIs。如果仅想支持几项,可如下配置:

android {
  ...
  defaultConfig {
    ...
    externalNativeBuild {
      cmake {...}
      // or ndkBuild {...}
    }

    ndk {
      // Specifies the ABI configurations of your native
      // libraries Gradle should build and package with your APK.
      abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a',
                   'arm64-v8a'
    }
  }
  buildTypes {...}
  externalNativeBuild {...}
}

如果想控制生成多种ABI,又仅想把其中几个ABI生成的so打包进apk中,那么可以在

defaultConfig.externalNativeBuild.cmake {} 

 (以ndk-build构建的,则在defaultConfig.externalNativeBuild.ndkBuild {}) 下再添加一个abiFilters标识

 只有defaultConfig.ndk{abiFilters }配置的abi才会打包进Apk中


如果想为每一种ABI生成单独的apk,参见 configuring ABI APK splits

例如

android {
  ...
  splits {

    // Configures screen ABI split settings
    abi {

      // Enable ABI APK splits
      enable true

      // By default all ABIs are included, so use reset() and include to specify that we only
      // want APKs for x86, armeabi-v7a, and mips

      // Resets the list of ABIs that Gradle should create APKs for to none
      reset()

      // Specifies a list of ABIs that Gradle should create APKs for
      include "x86", "armeabi-v7a", "mips"

      // Specify that we do not want to also generate a universal APK that includes all ABIs
      universalApk false
    }
  }
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值