Android Studio使用jni环境配置
使用AndroidStudio编写原生层应用,有两种方式:
1,官方示例,Gradle+Cmake+LLDB+NDK
官方示例,如何向安卓中添加C/C++代码
2,老方法通过NDK中的ndk-build编译Android.mk文件
官方的示例可以通过上述链接查看,有个缺点就是有时候会因为无法翻的问题,得通过自己去下载配置Cmake和LLDB这些工具。
因此,本文详细说明方法2,传统原生编写应用方法在AndroidStudio中的应用。
主要步骤:
1,下载NDK,ndroid-ndk-r13b
2,在app/build.gradle中添加sourceSets
3,配置javah,ndk-build命令
4,添加NDK支持
5,创建jni文件夹,build -> Make Project
6,调用javah命令
7,编写Android.mk,Application.mk文件
8,编写XXX.cpp,实现.h文件中的方法
9,调用ndk-build命令
1-4步是环境配置步骤
5-9步则是安卓应用的动态库创建的过程
详解:
1,下载ndk
这里要注意一下,最好下载高版本的ndk,有时候低版本的ndk会报错。。。不知道为什么
2,在app/build.gradle中添加代码
sourceSets.main{
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
jni.srcDirs = []代表告诉gradle,jni中的文件交给我们自己来处理,不需要gradle帮忙处理,而由我们手动调用ndk-build方式去生成so动态链接库;
jniLibs.srcDir ‘src/main/libs’代表我们生成的库文件(.so)所存放的位置;
app/build.gradle完整代码
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.yyt.myinject"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
//如果要gradle来生成so库,则需要下列代码,可能还需要指定加载的其他库
//这几行代码相当于Android.mk和Application.mk两个文件的作用
// ndk {
// moduleName "MyLibrary" //库名称
// abiFilters "armeabi" //指定平台类型
// }
}
sourceSets.main{
jni.srcDirs = []
jniLibs.srcDir 'src/main/libs'
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
………………
}
3,配置javah,ndk-build命令
javah是通过java文件生成jni调用的.h头文件的命令。
ndk-build是用来编译动态库的命令。
一般的做法是点击AS下方的Terminal控制台,通过控制台进入指定目录下调用上述命令。这就比较麻烦。
参考这篇文章中的External Tools的方法定义javah和ndk-build命令
超级简单的Android Studio jni 实现(无需命令行)
打开File-Settings-Tools-External Tools
点击+号新建命令:
主要是看Tool settings中的填写:
Program:指的是要运行的文件的地址,即命令所对应的程序的绝对路径,$JDKPath$ 是指JDK所在的文件路径,是通过右侧的Insert macro按钮添加的,里面还有很多参数。
Parameters:指的是命令执行的参数,这里的参数有两个,第一个是类文件所在的目录,第二个是目标类文件名称
Working directory:指的是该命令在哪个文件夹下执行,即当前目录是什么。
再添加ndk-build命令:
在Windows下面ndk-build好像无法直接访问,只能访问ndk-build.cmd命令行代码。
4,添加NDK支持
File -> Project Structure ->SDK Location ->Android NDK location中添加下载的NDK的根目录地址
5,创建jni文件夹,然后build -> Make Project
然后点击build -> Make Project生成 .class文件
6,调用javah命令
右键待生成.h头文件的类文件,选择在External Tools中定义的javah命令。
当我们右键我们要生成头文件的java类文件MainActivity调用External Tools中的javah命令时执行的命令是:
会在jni文件夹创建出一个com_yyt_myinject_MainActivity.h文件。
7,编写Android.mk,Application.mk文件
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyInject
LOCAL_SRC_FILES := com_yyt_myinject_MainActivity.cpp
LOCAL_LDLIBS := -lm -llog
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir),第一行好像都是这样子。。表示当前路径是调用的路径
include $(CLEAR_VARS) 表示清楚之前的参数定义和申明,如果一个mk文件中包含多个库需要编译,每个库之间都要调用include $(CLEAR_VARS)
LOCAL_MODULE := MyInject 是动态库的库名称,和MainActivity中的System.load(“MyInject”) 语句中的待加载的动态库的名称对应
LOCAL_SRC_FILES := com_yyt_myinject_MainActivity.cpp 表示当前动态库需要包含的源代码
LOCAL_LDLIBS := -lm -llog 表示当前需要用到的其他的库函数,包括系统的和第三方的
include $(BUILD_SHARED_LIBRARY) 好像是表示编译的库的类型
Application.mk
APP_MODULES := MyInject
APP_ABI := armeabi
表示需要编写的库对应的平台类型,即机器指令的类型。
8,编写XXX.cpp,实现.h文件中的方法
我们如果发现在编写CPP文件时,AS没有进行自动的代码不全时,我们需要进行一个设置。
File -> Link C++ Project with Gradle
Build System 选择ndk-build
Project Path 选择当前项目对应的Android.mk文件的路径
9,调用ndk-build命令
同第六步,右键jni文件夹,调用External Tools中的ndk-build命令。