文章目录
转载请注明链接
ubuntu系统14.04
Android Studio 2.3->3.2
先说Android Studio 2.3
1、生成.h文件
此操作网上教程颇多,此处不做研讨。
2、配置gradle
首先创建src/main/jni目录,将cpp文件放在里面,在build.gradle的android标签内添加:
defaultConfig {
ndk {
moduleName "RadioJni"//指定生成的so文件名
abiFilters "armeabi-v7a"//指定需要生成的so运行平台,此处非常关键
ldLibs "log", "radio"//依赖liblog.so及libradio.so
}
}
sourceSets { main { jni.srcDirs = ['src/main/jni', 'src/main/jni/'] } }
上述配置说明如下:
liblog.so是ndk中自带的,无须配置
libradio.so是framework开发人员提供,类比liblog,考虑放到下载ndk开发环境目录中。其是在ndk对应的sdk版本目录下寻找,比如sdk用的是18,则需要将libradio.so复制到ndk的android-18目录下。
重点注意:
libradio.so复制到那个架构目录下呢? abiFilters “armeabi-v7a”,这里能否加上intel等架构吗?
不能加其他架构,这个libradio.so framework在生成时就是armeabi-v7a架构的,所以只能生成armeabi-v7a架构的libRadioJni.so,这样libradio.so也只能复制到ndk android-18目录下的armeabi-v7a目录。
3、配置gradle.properties
如有以下错误:
Error:(12, 0) Error: NDK integration is deprecated in the current plugin.
Consider trying the new experimental plugin.
For details, see http://tools.android.com/tech-docs/new-build-system/gradle-experimental.
Set “android.useDeprecatedNdk=true” in gradle.properties to continue using the current NDK integration.
可在gradle.properties文件中添加一行代码:
android.useDeprecatedNdk = true
配置完毕后,编译生成apk即可。
Android 3.2
Android 3.2后上述方案无法实行了,默认是CMake方式编译,会提示有C++需要CMake编译,这样这个编译配置变得更复杂了。
不过在旧的项目上可以右击项目,选择Link C++ Project with Gradle,编译方式可以使用ndk-build方式,需要指定mk文件,这个没有尝试,应该可以避免未知的CMake配置。
首先需要创建一个include c++ Support的工程,这样就会生成以下配置:
1、gradle
首先看gradle文件,android节点下添加:
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
defaultConfig节点下添加:
externalNativeBuild {
cmake {
cppFlags "-std=c++14"
}
}
2、CPP
与Java节点同级多了一个cpp的节点,对应目录为src\main\cpp,与src\main\java同级,默认只有一个native-lib.cpp文件
3、CMakeLists.txt
在app目录下多了一个CMakeLists.txt文件。
# For more information about using CMake with Android Studio, read the
# documentation: <a rel="external nofollow" href="https://d.android.com/studio/projects/add-native-code.html">https://d.android.com/studio/projects/add-native-code.html
</a># 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.
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 this
# 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} )
这样旧有项目上用CMake方式的话,需要手动创建并指定这个CMakeLists.txt。
4、CMakeLists.txt的修改(来自https://www.jb51.net/article/129883.htm)
–设置其他后缀文件(例如.S汇编文件)为可编译源文件:
set_property(SOURCE src/main/cpp/art/art_quick_dexposed_invoke_handler.S PROPERTY LANGUAGE C)
–设置多个不定数量的源文件(也即使用*星号通配符的方式):
file(GLOB native_srcs "src/main/cpp/*.cpp" "src/main/cpp/dalvik/*.cpp" "src/main/cpp/art/*.cpp" "src/main/cpp/art/*.S")
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).
${native_srcs}
)
–链接三方SO库文件(例如我需要使用三方的libsubstrate.so库做测试):
file(GLOB libs src/main/cpp/3rd/libsubstrate.so src/main/cpp/3rd/libsubstrate-dvm.so)
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${libs}
${log-lib} )