概念:
Android NDK 是在SDK前面又加上了“原生”二字,即Native Development Kit,因此又被Google称为“NDK”。JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C、C++)。从Java1.1开始,JNI标准成为java平台的一部分,它允许Java代码和其他语言写的代码进行交互。
目标:
本文将细述在 Android Studio环境下进行NDK开发的的安全,个人感觉Android Studio目前对NDK支持还不是很完善,因为一些工作还需要用其他工具去完成。
环境
笔者的开发环境是 Windows 10, Android Studio 2.1.1 ,NDKr10
首先创建一个JNILib Class:
public class JNILib {
static {
System.loadLibrary("JNILib");
}
//string array
public static native String[] stringMethod();
}
Build—>Make Module 'app',这样JNILib就编译完成了
通过JNILib.class,用javah生成C的头文件,
生成的JNI 目录和C 头文件
打开头文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_qinghua_liu_myapplication_JNILib */
#ifndef _Included_com_example_qinghua_liu_myapplication_JNILib
#define _Included_com_example_qinghua_liu_myapplication_JNILib
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_qinghua_liu_myapplication_JNILib
* Method: stringMethod
* Signature: ()[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_com_example_qinghua_1liu_myapplication_JNILib_stringMethod
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
在jni目录创建C 文件,代码如下:
#include "com_example_qinghua_liu_myapplication_JNILib.h" const static int length=10; //string array JNIEXPORT jobjectArray JNICALL Java_com_example_qinghua_1liu_myapplication_JNILib_stringMethod (JNIEnv *env, jclass obj) { jclass class=(*env)->FindClass(env,"java/lang/String"); jobjectArray string=(*env)->NewObjectArray(env,(jsize)length, class,0); jstring jstr;这里要提醒一下,jni目录需要要有两个以上.c文件 否则Android Studio build 会出错,这应该是一个官方的坑。char* _char[]={"欢 ","迎 ","了解", "NDK","和","JNI", "相关","开发","编程","技术!" };
int i=0; for(;i<length;++i) { jstr=(*env)->NewStringUTF(env,_char[i]); (*env)->SetObjectArrayElement(env,string,i,jstr); } return string; }
那么再建一个empty.c
Build:
在local.properties中加入ndk路径:
ndk.dir=C\:\\Users\\Qinghua_Liu.ASUSCN\\AppData\\Local\\Android\\android-ndk32-r10b-windows-x86_64\\android-ndk-r10b
在项目的的build.gradle中defaultConfig中加入ndk moduleName定义,如下:
Activity 中调用JNI:
btn2 = (Button) findViewById(R.id.mybutton2);
new JNITask(btn2).execute();
public class JNITask extends AsyncTask<Void,Integer,String> {
private final WeakReference<Button> btn;
StringBuilder s = new StringBuilder();
public JNITask(Button btni) {
btn = new WeakReference<Button>(btni);
}
@Override
protected String doInBackground(Void... params) {
String[] temp = JNILib.stringMethod();
for (int i = 0; i < temp.length; i++) {
s.append(temp[i]);
}
return s.toString();
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected void onPostExecute(String s1) {
super.onPostExecute(s1);
if (btn != null) {
final Button btnDone = btn.get();
final String sdone =s1;
if (null != btnDone) {
btnDone.post(new Runnable() {
@Override
public void run() {
btnDone.setText(sdone);
}
});
}
}
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected void onCancelled(String s) {
super.onCancelled(s);
}
@Override
protected void onCancelled() {
super.onCancelled();
}
}
运行结果:成功调用并设字串到Button text
下载Link ndk
http://wear.techbrood.com/tools/sdk/ndk/