Android Studio 配置 NDK(一)
什么是ndk, 简单的讲就是ndk可以让你调用到c/c++方法来实现一些比较安全的功能,例如你完全可以将Android程序的数据 通过c/c++原来编写存储, 然后通过jni方式调用方法,而且在实现的时候, 也可以各种加密,让后程序的数据更加安全。
最近想给项目应用增量更新,所以就折腾了一下ndk。
和以往的ndk开发方式不太一样。
1.现在查到的资料大部分套路都是需要先通过javah文件方式生成.h文件, 然后写对应的实现文件.c /. cpp,最终配置文件android.mk, Application.mk,放在jni目录下, 执行ndk-build命令,最终生成可用的.so库
2.使用官方提供的gradle-experimental插件(gradle的版本和插件版本要对应),照着官方文档在gradle中一顿配置后, 编写native 方法,alter+enter键,最终还是未出来。
最终发现, 其实现在的android studio都是很智能,配置好模块,make project的时候自动帮你编译生成.so库文件, 基本上不用配置什么,最终还是能很容易的就编出hello world。这里只是简单的讲一下ndk建立项目的一些初步问题, 高手请绕道。
1.新建立一个项目:
2.配置gradle
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "com.caldremch.myapplication"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
ndk{
moduleName = "cade"
//abiFilters "x86","armeabi-v7a" //这里填写两个abi cpu架构,如果什么都不写,则默认支持所有平台
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
3.建立一个类 ,包含native方法,此时会有看到方法是红色的, 这很正常的
public class JNITest {
static {
System.loadLibrary("cade"); //这里的cade跟gradle配置的modulename一致
}
public native String getAA(); //native方法
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
4.切刀Java目录 ,输入命令.javah -d ../jni 包名.类名(例如com.cade.utils.JNITest)
,生成.h文件, 编写对应的.c文件
hello.c文件为:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <string.h>
#include "hello.h" //这里注意, 如果刚才没有改文件名,那么这里就不是hello.h了
jstring Java_com_caldremch_myapplication_JNITest_getAA
(JNIEnv * env, jobject clazz)
{
return (*env)->NewStringUTF(env, "测试成功没有");
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
准备工作已经差不多了, 接下里还要在gradle.properties文件中加上一句:
android.useDeprecatedNdk=true //不加有可能导致编译不成功
- 1
- 2
- 1
- 2
执行编译:菜单栏 build—》make project(��图标)
在MainActivity中引测试:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.text);
textView.setText(new JNITest().getAA());
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
接下来我们看看到底.so库在哪里生成了?
看到结果了吧。
这里说几点:
1.配置不让gradle自动编译,自己编译,那么在build.gradleandroid节点下设置
// sourceSets.main{
// jni.srcDirs = []//设置禁止gradle生成Android.mk
// jniLibs.srcDirs = ['src/main/jniLibs']//设置目标的so存放路径
// }
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
2.如果一个项目中,有多个引用的.so库, 请注意一点, 一定让它们支持的cpu abi数量和类型 一样。不然会报错 java.lang.UnsatisfiedLinkError
例如在一同一个项目中有ndk模块
ndk {
moduleName = 'module1'
abiFilters "x86","armeabi-v7a"
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
在另一个依赖项目:
ndk {
moduleName = 'module2'
abiFilters "x86","armeabi-v7a"
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
如果它们 abiFilters不一样,数量或者类型有别, 那么将导致错误。