开始之前的话:
1:本系列的开发,全部是在AS3.0的基础上进行。
2:文章上会对一些常犯错的以及需要注意的地方加以说明。
3:概念性的东西,就不在此啰嗦,我会在必要的地方加上详尽的注释。
一:搭建环境(2种方式)
1:直接在AS进行下载
File-> Settings ->Apperance&Behavior ->SystemSettings ->AndroidSDK,如图
下载完之后其实就可以了,你可以在你的Android\Sdk目录下找到一个ndk-bundle的文件夹,比如我的
PS:你可以在系统的环境变量配置一下你的ndk-build命令,这个不细讲。
2:直接下载离线包
下载地址:https://developer.android.google.cn/ndk/downloads/index.html
找到对应的平台,对应版本,这个不需要翻墙的。
下载完解压后把所有的文件拷贝到\Android\Sdk\ndk-bundle这个目录下重启AS就可以了。
关于配置
很多文章中都说到要配置local.properties和gradle.properties,甚至在3.0以下,app下的build.gradle文件也是需要配置的,3.0中都自动帮你生成好了,需要熟悉也可以去看一下。
二:AS自带Demo的讲解
新建项目,看图
项目创建完之后,你会发现,AS已经给你准备好了一个带有JNI的项目,下面我们来看看。
native-lib.cpp 介绍:
/**
* 这个头文件在ndk-bundle\platforms\android-x(x是版本号)\arch-x(x是CPU架构)\usr\include
* 目录下可以找到
*
* 多看这个头文件,会有助于你对JNI的理解,
*
* 或者可以直接在AS上,按住Ctrl,把鼠标移到JNIEnv上打开这个头文件
*
* **/
#include <jni.h>
#include <string>
/**
* extern "C" 这句话,后面你添加的每一个方法前面都要加上该句,
* 不然就会报找不到native方法的错误。
*
* JNIEXPORT 和 JNICALL 是两个宏,此处可以加,也可以不加。
*
* jstring 是 Java中String类在JNI对应的写法,每一个类都要在前面加上一个j,
* 并把开头的大写变小写,如下面的jobject
*
* 方法名命名规则:Java_ + 包名(包名把 .统一改成 _ )+ 类名 + native方法名,
* 看下面这个方法名就应该很好理解。
*
* JNIEnv 是 JNINativeInterface 接口的一个别名,在括号中的参数是一个二级指针,
* 这里理解成Java中的一个类就好了,基本上这个参数是必加的。
* **/
extern "C"
JNIEXPORT jstring JNICALL
Java_com_luosiye_jni_MainActivity_stringFromJNI(JNIEnv *env, jobject /* this */) {
std::string hello = "Hello from C++";
/**
* env->是C++中二级指针调用它本身方法的一种写法,
* 要很好的理解这些东西,学C++是必不可少,包括后面的学习和使用
* **/
return env->NewStringUTF(hello.c_str());
}
CMakeLists.txt 介绍,实际上我需要关心的只有两部分,
添加库
#添加可执行文件所需要的库
add_library( # Sets the name of the library.
native-lib # so库名
# Sets the library as a shared library.
SHARED
# 添加源文件
# Provides a relative path to your source file(s).
src/main/cpp/native-lib.cpp )
链接库
# 链接上可执行文件所需要的库
target_link_libraries( # Specifies the target library.
native-lib #关联so库名
# Links the target library to the log library
# included in the NDK.
${log-lib} )
实际上CMakeLists.txt还可以添加很多东西,比如,项目名称,头文件,设置环境变量等,这部分知识大家自己上网搜。
再来看build.gradle,添加的内容也是两部分
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
defaultConfig {
applicationId "com.luosiye.jni"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
//添加的第一部分内容
externalNativeBuild {
cmake {
//这里面,里面可以是C++11,也可以是C++14,甚至什么内容都不需要
cppFlags "-frtti -fexceptions"
// 添加需要支持的CPU架构,这部分AS生成时是没有的,是我自己加上去的。
abiFilters "arm64-v8a","armeabi","armeabi-v7a","mips","mips64","mips64","x86","x86_64"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
//添加的第二部分内容
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
关于so库文件
生成目录如下图
PS:这里需要注意的一点是,如果你是Rebuild,那么会把所有CPU类型的so库编译出来,如果你是用手机运行的,那么只会编译你手机CPU类型架构的so文件
今天这篇就先讲这些,下一篇我将和大家讲一下,如何编码和生成自己的so文件库。