AndroidStudio NDK环境3种搭建方式

 
 
转载。 https://blog.csdn.net/zhang_jun_ling/article/details/85621427

一、前言

如今Android开发IDE都是使用的AndroidStudio,之前我写过一篇文章介绍的是如何在Eclipse中搭建NDK环境 Android NDK --初始android NDK
这边博客介绍下在AndroidStudio中搭建NDK环境的三种方式。

二、知识点概述

本片我们将从以下几点初步认识、创建Android NDK:
1.Java加载/调用NDK端的代码;
2.本地 c++代码的编写;
3.编写构建系统文件(android.mkapplication.mk
4.通过构建系统编译c++代码
4.1、通过Gradle搭建NDK环境;
4.2、通过NDKBuild搭建NDK环境(重点介绍);
4.3、通过CMake搭建NDK环境;

三、知识点详解

(1)Java加载/调用NDK端的代码

1、Java端代码:

public class MainActivity extends AppCompatActivity {

    static {
System.loadLibrary("helloworld");
} private TextView mDataView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); initView();
} private void initView() {
mDataView = (TextView) this.findViewById(R.id.tv_data);
mDataView.setText(getStrFromNative());
} private native String getStrFromNative();
}

2、在AndroidStudio打开命令行界面,cd app/src/main/java 运行

javah com.zhangjunling.ndk_environment_gradle.MainActivity
  • 1

这时会自动在目录下生成一个com_zhangjunling_ndk_environment_gradle_MainActivity.h文件,把文件拷贝到 main/jni 目录中。

(2) 本地 c++代码的编写

由于本编只是介绍NDK环境的搭建问题,所以代码越简单越容易把所有的精力都放在环境搭建上,所以c++代码只是简单的 HelloWrold程序;

helloworld.cpp

#include "com_zhangjunling_ndk_environment_gradle_MainActivity.h"

JNIEXPORT jstring JNICALL Java_com_zhangjunling_ndk_1environment_1gradle_MainActivity_getStrFromNative
(JNIEnv *env, jobject obj){
return env->NewStringUTF("Hello. I'm form native");
}

(3)编写构建系统文件

在jni目录下创建Android.mk、Application.mk文件内容如下:
Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := helloworld
LOCAL_SRC_FILES := helloworld.cpp include $(BUILD_SHARED_LIBRARY)

Application.mk

APP_STL := gnustl_static
APP_ABI := armeabi

关于构建系统里面的键值对的含义,现在先不关心,下篇文章我会详细介绍;

(4)通过构建系统编译c++代码

通过Gradle搭建NDK环境

Gradle是androidstudio上的编译工具,我们可以通过从项目下的local.properties获取ndk.dir=xxxxxxxx,获取ndk-build路径,然后执行ndk-build便可以编译出需要的动态库文件;gradle的语法这里不在进行讲解,感兴趣的可以从网络上获取资料学习;
build.gradle代码如下:

import org.apache.tools.ant.taskdefs.condition.Os

apply plugin: 'com.android.application'

android {
compileSdkVersion 28
defaultConfig {
applicationId "com.zhangjunling.ndk_environment_gradle"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
} sourceSets {
main {
jniLibs.srcDir 'src/main/libs'
jni.srcDirs = []
}
}
} tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
} String getNdkBuildPath() {
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkBuildingDir = properties.getProperty("ndk.dir")
def ndkBuildPath = ndkBuildingDir
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
ndkBuildPath = ndkBuildingDir + '/ndk-build.cmd'
} else {
ndkBuildPath = ndkBuildingDir + '/ndk-build'
}
return ndkBuildPath
} task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
println('executing ndkBuild')
def ndkBuildPath = getNdkBuildPath();
commandLine ndkBuildPath, '-j8', '-C', file('src/main').absolutePath
} task ndkClean(type: Exec, description: 'clean JNI libraries') {
println('executing ndkBuild clean')
def ndkBuildPath = getNdkBuildPath();
commandLine ndkBuildPath, 'clean', '-C', file('src/main').absolutePath
}
clean.dependsOn 'ndkClean' dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
  • 1过工具栏 Build/ReBuild Project,观察到libs目录、obj目录自动产生,没有报错。这可以说明我们的配置没有什么问题;可以运行项目看到:
Hello. I'm form native
通过NDKBuild搭建NDK环境(重点介绍)

通过ndk-build交叉编译c++本地代码是我们重点学习的,后面我会重点介绍通过ndk-build交叉编译出我们需要的动态库。本篇只介绍环境的搭建。
Android.mk构建好了之后,ndk-build环境就比较简单了,步骤:

项目右键->Link C++ Project With Gradle 
路径选择Android.mk 就OK 了。
通过CMake搭建NDK环境

CMake搭建NDK环境有两种方式:
1、与ndk-build相同

项目右键->Link C++ Project With Gradle 
路径选择CMakeList.txt 就OK 了。

2、在Create Android Project的时候底部勾选Include C++ support,项目创建好了之后,自动创建好了NDK环境。我们可以在此基础上开发NDK。

项目路径:AndroidStudio环境搭建源码

 
三种方法 app/build.gradle文件内容如下:
import org.apache.tools.ant.taskdefs.condition.Os
apply plugin: 'com.android.application' android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.myapplication"
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" ndk {
moduleName "Test"
ldLibs "log"
// abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库,目前可有可无
} // 使用Cmake工具-way1
//start way1
// externalNativeBuild {
// cmake {
// cppFlags ""
// abiFilters 'arm64-v8a','armeabi-v7a','x86','x86_64'
// }
// }
} // // 配置CMakeLists.txt路径-way1
// externalNativeBuild {
// cmake {
// path "CMakeLists.txt" // 设置所要编写的c源码位置,以及编译后so文件的名字
// }
// end way2 // 设置按android.mk 进行编译-way2
//start way2
externalNativeBuild {
ndkBuild {
path "src/main/jni/Android.mk"
}
}
//end way2
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' }
} // sourceSets.main {
// jni.srcDirs = ['src/main/jni', 'src/main/jni/']
// jniLibs.srcDirs "src/main/libs"
// }
sourceSets {
main {
jniLibs.srcDir 'src/main/libs'
jni.srcDirs = []
}
}
compileOptions {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
buildToolsVersion = '28.0.3' }
/*
//begin -- way3
tasks.withType(JavaCompile) {
compileTask -> compileTask.dependsOn ndkBuild
} String getNdkBuildPath() {
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
def ndkBuildingDir = properties.getProperty("ndk.dir")
def ndkBuildPath = ndkBuildingDir
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
ndkBuildPath = ndkBuildingDir + '/ndk-build.cmd'
} else {
ndkBuildPath = ndkBuildingDir + '/ndk-build'
}
return ndkBuildPath
} task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
println('executing ndkBuild')
def ndkBuildPath = getNdkBuildPath();
commandLine ndkBuildPath, '-j8', '-C', file('src/main').absolutePath
} task ndkClean(type: Exec, description: 'clean JNI libraries') {
println('executing ndkBuild clean')
def ndkBuildPath = getNdkBuildPath();
commandLine ndkBuildPath, 'clean', '-C', file('src/main').absolutePath
}
clean.dependsOn 'ndkClean'
//end-way3
*/
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:2.0.0-alpha4'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

在app/build.gradle同目录下的CMakeLists.txt文件内容如下:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library.
#CMakeLists.txt
#指定需要CMake的最小版本
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.
# 设置so文件名称.
Test # Sets the library as a shared library.
SHARED
# 设置这个so文件为共享. # Provides a relative path to your source file(s).
# 设置这个so文件的源码文件.
src/main/jni/Test.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.
# 制定目标库.
Test # Links the target library to the log library
# included in the NDK.
${log-lib} )

在jni目录下的Android.mk内容如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := Test
LOCAL_SRC_FILES := Test.cpp LOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY)

在jni目录下的Application.mk内容如下:

APP_MODULES := Test
APP_PLATFORM := android-16
APP_ABI := all

AndroidStudio NDK环境3种搭建方式的更多相关文章

  1. yum源仓库的三种搭建方式

    yum源的三种搭建方式 一.  本地yum仓库的搭建 1.1.获取软件包资源 将iso镜像挂载在本地目录中,此次挂载目录为/var/www/html/repo/,此目录本身不存在,需要创建.软件宝资源 ...

  2. Android ndk另一种注册方式

    不使用Java_com_xxx方式调用ndk的方式,这种方法的优点是灵活,可配置,不必限制在Java_com_xxx命名依赖中. 步骤如下: 第1步,在JNI初始化方法中调用自定义注册方法,并判断成功 ...

  3. NDK环境搭建(Native Code的编译,不需要Cygwin)

    分类: android2013-06-21 15:49 475人阅读 评论(0) 收藏 举报 Android NDK 目录(?)[-] System and Software Requirements ...

  4. Ubuntu 搭建NDK环境

    一. NDK下载地址 https://developer.android.com/tools/sdk/ndk/index.html 二. NDK环境两种方式 NDK下载后,解压缩后放置于目录/home ...

  5. 【转】Windows环境下Android NDK环境搭建

    原文网址:http://www.metsky.com/archives/525.html 前面介绍Windows下Android 开发环境配置,主要是面向JAVA开发环境,对只做APK上层应用开发人员 ...

  6. Windows环境下Android NDK环境搭建

    前面介绍Windows下Android 开发环境配置,主要是面向JAVA开发环境,对只做APK上层应用开发人员来讲,基本够用了,由于Linux系统的权限限制和Android封装架构限制,很多涉及底层设 ...

  7. Hadoop 学习笔记 (八) hadoop2.2.0 测试环境部署 及两种启动方式

    1基本流程步骤1:准备硬件(linux操作系统)步骤2:准备软件安装包,并安装基础软件(主要是JDK)步骤3:修改配置文件步骤4:分发hadoop步骤5:启动服务步骤6:验证是否启动成功!2硬件配置要 ...

  8. Windows XP环境下 搭建Android NDK环境

    搭建Android NDK环境 Windows XP环境下 1 一些下载 ① NDK r7:http://developer.android.com/sdk/ndk/index.html ② cygw ...

  9. 介绍几种搭建Dojo环境的方法

    Hello World! 的时间到了,在你所学过的众多语言中,哪个不是从此学起的呢?但在此之前,我们要先构建一个开发环境,如同刚开始学习Java的时候,还是需要我们先安装JDK.配置好环境变量等等,H ...

随机推荐

  1. Dedecms限制栏目列表生成的最大页数

    首先,我们要登陆DEDECMS后台 >> 系统 >> 站点设置 的同条栏目上,添加一个新的变量,变量名称:cfg_listmaxpage,变量说明:栏目生成列表最大页数,变量值 ...

  2. Dart 面向对象 类 方法

    Dart是一门使用类和单继承的面向对象语言,所有的对象都是类的实例,并且所有的类都是Object的子类. 面向对象编程(OOP)的三个基本特征是:封装.继承.多态 封装:封装是对象和类概念的主要特性. ...

  3. Mac上使用sunlogin向日葵软件远程控制电脑

    1 安装软件 控制端和客户端都安装 https://sunlogin.oray.com/personal/download/ 2 再两台电脑上都安装好客户端和控制端后,打开控制端软件 可以看到自己登录 ...

  4. 在DjangoAdmin中使用KindEditor(上传图片)

    一.下载 http://kindeditor.net/down.php 删除asp.asp.net.php.jsp.examples文件夹 拷贝到static目录下 二.配置 kindeditor目录 ...

  5. subs函数

    matlab中subs()是符号计算函数,表示将符号表达式中的某些符号变量替换为指定的新的变量,常用调用方式为: subs(S,OLD,NEW) 表示将符号表达式S中的符号变量OLD替换为新的值NEW ...

  6. Some ML Tutorials

    VAE: What-is-variational-autoencoder-vae-tutorial Variational-autoencoders-explained Building variat ...

  7. BZOJ 4823 老C的方块

    把格子分成四类 第一类是蓝线左右的相邻两个格子 第二类为与蓝线左边格子相邻的点 第三类为与蓝线右边格子相邻的点 建边就S朝第二类每个点建边 第二类每个点朝其相邻的第一类建边 第一类从左格子朝右格子建边 ...

  8. [USACO19JAN]Train Tracking 2——神仙结论题+DP

    原题链接 orz xzz巨佬 首先发现一个结论:两个相邻的\(c\)值如果不相同的话,就可以固定某个位置的值了 这启示我们把连续且相等的\(c\)给单独拿出来看,也就是对于一些\(c_i=c_{i+1 ...

  9. [AHOI2007]密码箱 (数学 + 暴力)

    链接:https://ac.nowcoder.com/acm/problem/19877来源:牛客网 题目描述 在一次偶然的情况下,小可可得到了一个密码箱,听说里面藏着一份古代流传下来的藏宝图,只要能 ...

  10. 自己写的一个用于往文件中插入字符串及空格的bat

    @echo off echo pleas input the filename:set /p file= :while rem set j=0 非得写这儿 写下面:check 上面不行 希望大神指点s ...