配置NDK环境,进行简单Native开发
NDK下载
环境变量配置
为ndk和jdk配置环境目录保证javah命令和ndk-build命令可以直接在命令行使用。
为AndroidStudio工程配置NDK路径
打开local.properties
文件,添加ndk目录:
sdk.dir=C\:\\Users\\realhe\\AppData\\Local\\Android\\Sdk
ndk.dir=D\:\\ndk\\android-ndk-r10c
打开build.gradle
,在defaultConfig中添加ndk{}:
android {
compileSdkVersion 24
buildToolsVersion "24.0.0"
defaultConfig {
applicationId "com.example.realhe.myapplication"
minSdkVersion 19
targetSdkVersion 24
versionCode 1
versionName "1.0"
//配置处如下
ndk{
moduleName "test" //生成的so名字
abiFilters "armeabi", "armeabi-v7a", "x86" //输出指定三种abi体系结构下的so库
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//此处为调试配置,可选项
ndk {
debuggable = true
}
}
debug {
debuggable = true
//此处为调试配置,可选项
jniDebuggable = true
}
}
}
保存后可能发生
NDK integration is deprecated in the current plugin. Consider trying the new experimental plugin
解决方法为在gradle.properties
中添加一行:
android.useDeprecatedNdk=true
JNI初步
创建文件夹
new > Folder >JNI Folder
创建jni文件夹,默认目录为
app/src/main/jni
新建一个使用jni的类
public class Test {
static {
System.loadLibrary("test");//需要与前面的so文件名保持一致
}
public native String get();
public native void set(String str);
public native int getToken(int token);
}
导出Test类的native方法对应的头文件:
C:\Users\realhe\AndroidStudioProjects\MyApplication>
javah -classpath
app\build\intermediates\classes\debug\
-d
app\src\main\jni
com.example.realhe.myapplication.Test
上面参数的含义依次是javah
命令,classpath
路径
.class
文件所在的文件夹app\build\intermediates\classes\debug\
-d:输出.h到目标文件夹app\src\main\jni
(即前面我们制定的默认jni文件夹)
com.example.realhe.myapplication.Test
:含有native方法的类
注意这个地方一定要在项目根目录下使用,而不能切换到 Test
类的.class
文件所在目录直接使用
之后可以看到生成的头文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_realhe_myapplication_Test */
#ifndef _Included_com_example_realhe_myapplication_Test
#define _Included_com_example_realhe_myapplication_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_realhe_myapplication_Test
* Method: get
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_realhe_myapplication_Test_get
(JNIEnv *, jobject);
/*
* Class: com_example_realhe_myapplication_Test
* Method: set
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_example_realhe_myapplication_Test_set
(JNIEnv *, jobject, jstring);
/*
* Class: com_example_realhe_myapplication_Test
* Method: getToken
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_com_example_realhe_myapplication_Test_getToken
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
实现头文件中的方法
在默认的JNI文件夹中新建一个test.c
文件,包含上述头文件并实现其中的方法:
//
// Created by realhe on 2016/7/18.
//
#include "com_example_realhe_myapplication_Test.h"
static int count = 0;
JNIEXPORT jstring JNICALL Java_com_example_realhe_myapplication_Test_get
(JNIEnv *env, jobject obj){
return (*env)->NewStringUTF(env,"This is a test for NDK!");
}
/*
* Class: com_example_realhe_myapplication_Test
* Method: set
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_com_example_realhe_myapplication_Test_set
(JNIEnv *env, jobject ibj, jstring jsr){}
/*
* Class: com_example_realhe_myapplication_Test
* Method: getToken
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_com_example_realhe_myapplication_Test_getToken
(JNIEnv *env, jobject obj, jint jinvar){
return count++;
}
注意:此处由于ndk的一个BUG,在编译单个.c文件时会报错:
com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command 'D:ndkandroid-ndk-r10ndk-build.cmd'' finished with non-zero exit value 2
解决方法为在同级目录下增加一个empty.c的空文件即可。
使用Native方法
在MainActivity中使用Nativce方法设置TextView
的Text
:
TextView textView = (TextView)findViewById(R.id.tv_hello);
Test test = new Test();
String content = test.get();
for (int i = 0;i<10;i++){
content += ("\n("+ test.getToken(1) + ")");
}
textView.setText(content);
最后效果如下:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。