您的位置:首页 > 移动开发 > Android开发

android studio 2.2 利用NDK 开发

2016-10-22 09:40 519 查看

android studio 2.2 对C/C++ 的支持做了很大的改善, 现在利用android studio 编写C/C++ 库,  DEBUG C/C++ , so easy!!!   这对于常用到ndk开发的android开发者来说,是多么值得庆幸的事。

废话不多说,我只记录一下怎么使用  android studio 2.2 做ndk开发

首先是下载 NDK,LLDB,CMake
       打开android studio的SDK Manager,点击 SDK TOOLS, 勾选CMake ,LLDB,NDK 进行下载(如果被墙了, 这里有可能看不到哦)



这三个安装好, android studio的NDK开发环境就OK了,接下来就是NDK开发步骤了:

Create a New Project with C/C++ Support

Creating a new project with support for native code is similar to creating any other Android Studio project, but
there are a few additional steps:
In the Configure your new project section of the wizard, check the Include C++ Support checkbox.
Click Next.
Complete all other fields and the next few sections of the wizard as normal.
In the Customize C++ Support section of the wizard, you can customize your project with the following options:
C++ Standard: use the drop-down list to select which standardization of C++ you want to use. Selecting Toolchain Default uses the default CMake setting.
Exceptions Support: check this box if you want to enable support for C++ exception handling. If enabled, Android Studio adds the 
-fexceptions
flag to 
cppFlags
 in your
module-level 
build.gradle
 file, which Gradle passes to CMake.
Runtime Type Information Support: check this box if you want support for RTTI. If enabled, Android Studio adds the 
-frtti
 flag to 
cppFlags
 in your module-level 
build.gradle
 file,
which Gradle passes to CMake.

Click Finish.

After Android Studio finishes creating your new project, open the Project pane from the left side of the IDE and select the Android view. As shown in figure 2, Android Studio adds the cpp and External
Build Files
 groups:



Figure 2. Android view groups for your native sources and external build scripts.

Note: This view does not reflect the actual file hierarchy on disk, but groups similar files to simplify navigating your project.
The cpp group is where you can find all the native source files, headers, and prebuilt libraries that are a part of your project. For new projects, Android Studio creates a sample C++ source file, 
native-lib.cpp
,
and places it in the 
src/main/cpp/
 directory of your app module. This sample code provides a simple C++ function, 
stringFromJNI()
, that returns the string “Hello from C++”. You can learn how to add additional source
files to your project in the section about how to Create new native source files.The External Build Files group is where you can find build scripts for CMake or ndk-build. Similar to how 
build.gradle
 files tell Gradle how to build your app, CMake and ndk-build require
a build script to know how to build your native library. For new projects, Android Studio creates a CMake build script, 
CMakeLists.txt
, and places it in your module’s root directory. You can learn more about the contents of this build
script in the section about how to Create a Cmake Build Script.

Build and run the sample app

When you click Run 

,
Android Studio builds and launches an app that displays the text “Hello from C++” on your Android device or emulator. The following overview describes the events that occur in order to build and run the sample app:
Gradle calls upon your external build script, 
CMakeLists.txt
.
CMake follows commands in the build script to compile a C++ source file, 
native-lib.cpp
, into a shared object library and names it 
libnative-lib.so
, which Gradle then packages into
the APK.
During runtime, the app's 
MainActivity
 loads the native library using 
System.loadLibrary()
.
The library’s native function, 
stringFromJNI()
, is now availableto the app.
MainActivity.onCreate()
 calls 
stringFromJNI()
, which returns “Hello from C++”, and uses it to update the 
TextView
.

Note: Instant Run is not compatible with projects that use native code. Android Studio automatically
disables the feature.

If you want to verify that Gradle packages the native library in the APK, you can use the APK Analyzer:
Select Build > Analyze APK.
Select the APK from the 
app/build/outputs/apk/
 directory and click OK.
As shown in figure 3, you can see 
libnative-lib.so
 in the APK Analyzer window under 
lib/<ABI>/
.


Figure 3. Locating a native library using the APK Analyzer.

Tip: If you want to experiment with other Android apps that use native code, click File > New > Import Sample and select a sample project from theNdk list.

Add C/C++ Code to an Existing Project

If you want to add native code to an existing project, perform these steps:
Create new native source files and add them to your Android Studio
project.
You can skip this step if you already have native code or want to import a prebuilt native library.

Create a CMake build script to build your native source code
into a library. You also require this build script if you are importing and linking against prebuilt or platform libraries.
If you have an existing native library that already has a 
CMakeLists.txt
 build script, or uses ndk-build and includes an 
Android.mk
 build
script, you can skip this step.

Link Gradle to your native library by providing a path to your CMake
or ndk-build script file. Gradle uses the build script to import source code into your Android Studio project and package your native library (the SO file) into the APK.

Once you configure your project, you can access your native functions from Java code using the JNI
framework. To build and run your app, simply click Run 

.
Gradle adds your external native build process as a dependency to compile, build, and package your native library with your APK.

Create new native source files

To create a 
cpp/
 directory with new native source files in the main sourceset of your app module, proceed as follows:
Open the Project pane from the left side of the IDE and select the Project view from the drop-down menu.
Navigate to your-module > src, right-click on the main directory, and select New > Directory.
Enter a name for the directory (such as 
cpp
) and click OK.
Right-click on the directory you just created and select New > C/C++ Source File.
Enter a name for your source file, such as 
native-lib
.
From the Type drop-down menu, select the file extension for your source file, such as 
.cpp
.
You can add other file types to the drop-down menu, such as 
.cxx
 or 
.hxx
, by clicking Edit File Types 

.
In the C/C++ dialog box that pops up, select another file extension from the Source Extension and Header Extension drop-down menus and click OK.

If you also want to create a header file, check the Create an associated header checkbox.
Click OK.

Create a CMake build script

If your native sources don’t already have a CMake build script, you need to create one yourself and include the appropriate CMake commands. A CMake build script is a plain text file that you must name 
CMakeLists.txt
. This section covers
some basic commands you should include in your build script in order to tell CMake which sources to use when creating your native library.

Note: If your project uses ndk-build, you don’t need to create a CMake build script. You can link
Gradle to your native library by providing a path to your 
Android.mk
 file.

To create a plain text file that you can use as your CMake build script, proceed as follows:
Open the Project pane from the left side of the IDE and select the Project view from the drop-down menu.
Right-click on the root directory of your-module and select New > File.

Note: You can create the build script in any location you want. However, when configuring the build script, paths to your native source files and libraries are relative to the location of the build script.

Enter "CMakeLists.txt" as the filename and click OK.

You can now configure your build script by adding CMake commands. To instruct CMake to create a native library from native source code, add the
cmake_minimum_required()
 and 
add_library()
 commands
to your build script:
# Sets the minimum version of CMake required to build your native library.
# This ensures that a certain set of CMake features is available to
# your build.

cmake_minimum_required(VERSION 3.4.1)

# Specifies a library name, specifies whether the library is STATIC or
# SHARED, and provides relative paths to the source code. You can
# define multiple libraries by adding multiple add.library() commands,
# and CMake builds them for you. When you build your app, Gradle
# automatically packages shared libraries with your APK.

add_library( # Specifies 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 )


When you add a source file or library to your CMake build script using 
add_library()
, Android Studio also shows associated header files in the Projectview after you sync your project. However, in order for CMake to locate
your header files during compile time, you need to add the
include_directories()
 command
to your CMake build script and specify the path to your headers:
add_library(...)

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


The convention CMake uses to name the file of your library is as follows:

liblibrary-name.so


For example, if you specify "native-lib" as the name of your shared library in the build script, CMake creates a file named 
libnative-lib.so
. However, when loading this library in your Java code, use the name you specified in the CMake
build script:
static {
    System.loadLibrary(“native-lib”);
}


Note: If you rename or remove a library in your CMake build script, you need to clean your project before Gradle applies the changes or removes the older version of the library from your APK. To clean your project, select Build > Clean
Project
 from the menu bar.

Android Studio automatically adds the source files and headers to the cpp group in the Project pane. By using multiple 
add_library()
 commands, you can define additional libraries for CMake to build from
other source files.

Add NDK APIs

The Android NDK provides a set of native APIs and libraries that you may find useful. You can use any of these APIs by including the
NDK libraries in your project’s 
CMakeLists.txt
 script file.

Prebuilt NDK libraries already exist on the Android platform, so you don’t need to build them or package them into your APK. Because the NDK libraries are already a part of CMake’s search path, you don’t even need to specify the location of the library in your
local NDK installation—you only need to provide CMake with the name of the library you want to use and link it against your own native library.

Add the 
find_library()
 command to your CMake build
script to locate an NDK library and store its path as a variable. You use this variable to refer to the NDK library in other parts of the build script. The following sample locates the Android-specific
log support library and stores its path in 
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 )


In order for your native library to call functions in the 
log
 library, you need to link the libraries using the 
target_link_libraries()
 command
in your CMake build script:
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} )


The NDK also includes some libraries as source code that you need to build and link to your native library. You can compile the source code into a native library by using the 
add_library()
 command in your CMake build script. To provide
a path to your local NDK library, you can use the
ANDROID_NDK
 path variable, which Android Studio automatically defines for you.

The following command tells CMake to build 
android_native_app_glue.c
, which manages 
NativeActivity
 lifecycle
events and touch input, into a static library and links it to 
native-lib
:
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} )

Add other prebuilt libraries

Adding a prebuilt library is similar to specifying another native library for CMake to build. However, because the library is already built, you need to use the 
IMPORTED
 flag
to tell CMake that you only want to import the library into your project:
add_library( imported-lib
SHARED
IMPORTED )


You then need to specify the path to the library using the 
set_target_properties()
 command
as shown below.

Some libraries provide separate packages for specific CPU architectures, or Application Binary Interfaces (ABI), and organize
them into separate directories. This approach helps libraries take advantage of certain CPU architectures while allowing you to use only the versions of the library you want. To add multiple ABI versions of a library to your CMake build script, without having
to write multiple commands for each version of the library, you can use the 
ANDROID_ABI
 path variable. This variable uses a list of the default ABIs
that the NDK supports, or a filtered list of ABIs you manually configure Gradle to use. For
example:
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 )


For CMake to locate your header files during compile time, you need to use the 
include_directories()
 command and include the path to your header files:
include_directories( imported-lib/include/ )


Note: If you want to package a prebuilt library that is not a build-time dependency—for example, when adding a prebuilt library that is a dependency of 
imported-lib
, you do not need perform the following instructions to
link the library.

To link the prebuilt library to your own native library, add it to the 
target_link_libraries()
 command in your CMake build script:
target_link_libraries( native-lib imported-lib app-glue ${log-lib} )


When you build your app, Gradle automatically packages the imported library into the APK. You can verify which libraries Gradle packages into your APK by using the APK
Analyzer. For more information about CMake commands, see the CMake documentation."

Link Gradle to your native library

To link Gradle to your native library, you need to provide a path to your CMake or ndk-build script file. When you build your app, Gradle runs CMake or ndk-build as a dependency, and packages shared libraries with your APK. Gradle also uses the build script
to know which files to pull into your Android Studio project, so you can access them from the Project window. If you don’t have a build script for your native sources, you need to create
a CMake build script before you proceed.

Once you link Gradle to a native project, Android Studio updates the Project pane to show your source files and native libraries in the cpp group, and your external build scripts in the External Build Files group.

Note: When making changes to the Gradle configuration, make sure to apply your changes by clicking Sync Project 

 in
the toolbar. Additionally, when making changes to your CMake or ndk-build script file after you have already linked it to Gradle, you should sync Android Studio with your changes by selecting Build > Refresh Linked C++ Projects from the menu
bar.

Use the Android Studio UI

You can link Gradle to an external CMake or ndk-build project using the Android Studio UI:
Open the Project pane from the left side of the IDE and select the Android view.
Right-click on the module you would like to link to your native library, such as the app module, and select Link C++ Project with Gradle from the menu. You should see a dialog similar to the
one shown in figure 4.
From the drop-down menu, select either CMake or ndk-build.
If you select CMake, use the field next to Project Path to specify the 
CMakeLists.txt
 script file for your external CMake project.
If you select ndk-build, use the field next to Project Path to specify the 
Android.mk
 script
file for your external ndk-build project. Android Studio also includes the 
Application.mk
 file
if it is located in the same directory as your 
Android.mk
 file.



Figure 4. Linking an external C++ project using the Android Studio dialog.

Click OK.

Manually configure Gradle

To manually configure Gradle to link to your native library, you need to add the 
externalNativeBuild {}
 block to your module-level 
build.gradle
 file and configure it with either 
cmake {}
 or 
ndkBuild
{}
:
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"
}
}
}


Note: If you want to link Gradle to an existing ndk-build project, use the 
ndkBuild {}
 block instead of 
cmake {}
, and provide a relative path to your
Android.mk
 file.
Gradle also includes the 
Application.mk
 file if it is located in the same directory as your 
Android.mk
 file.
Specify optional configurations

You can specify optional arguments and flags for CMake or ndk-build by configuring another 
externalNativeBuild {}
 block within the 
defaultConfig {}
 block of your module-level 
build.gradle
 file.
Similar to other properties in the 
defaultConfig {}
 block, you can override these properties for each product flavor in your build configuration.

For example, if your CMake or ndk-build project defines multiple native libraries, you can use the 
targets
 property to build and package only a subset of those libraries for a given product flavor. The following code sample describes some
of the properties you can configure:
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_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 {...}
}
}


To learn more about configuring product flavors and build variants, go to Configure Build Variants. For a list of
variables you can configure for CMake with the 
arguments
 property, see Using CMake Variables.
Specify ABIs

By default, Gradle builds your native library into separate 
.so
 files for the ABIs the NDK supports and
packages them all into your APK. If you want Gradle to build and package only certain ABI configurations of your native libraries, you can specify them with the 
ndk.abiFilters
 flag in your module-level 
build.gradle
 file,
as shown below:
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 {...}
}


In most cases, you only need to specify 
abiFilters
 in the 
ndk {}
 block, as shown above, because it tells Gradle to both build and package those versions of your native libraries. However, if you want to control what
Gradle should build, independently of what you want it to package into your APK, configure another 
abiFilters
 flag in the 
defaultConfig.externalNativeBuild.cmake {}
 block (or 
defaultConfig.externalNativeBuild.ndkBuild
{}
block). Gradle builds those ABI configurations but only packages the ones you specify in the 
defaultConfig.ndk{}
 block.

To further reduce the size of your APK, consider configuring ABI APK splits—instead of
creating one large APK with the all versions of your native libraries, Gradle creates a separate APK for each ABI you want to support and only packages the files each ABI needs. If you configure an ABI split without specifying the 
abiFilters
 flag
as shown in the code sample above, Gradle builds all supported ABI versions of your native libraries, but only packages those you specify in your ABI split configuration. To avoid building versions of your native libraries that you don't want, provide the
same list of ABIs for both the 
abiFilters
 flag and your ABI split configuration.
这三个安装好, android studio的NDK开发环境就OK了,接下来就是NDK开发步骤了:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: