较新的NDK版本是r10b,Android Studio对NDK开发的支持还处于构思阶段,所以很多工作比如用javah生成头文件等工作还要自己做。今天用一个例子来演示AS中的NDK开发。
## 新建一个项目SecondNdkTest
在此项目中新建一个Module叫ndklibrary,作为so库单独划出来。在library中新建一个java类SecondLib,内容如下:
~~~
package com.linc.ndklibrary;
/**
* Created by linc on 15-3-29.
*/
public class SecondLib {
// Native implementation
static {
System.loadLibrary("SecondLib");
}
//int array
public static native int[] intMethod();
//string array
public static native String[] stringMethod();
}
~~~
Build—>Make Module’ndklibrary’,这样SecondLib就编译完成了,通过SecondLib.class,用javah生成C的头文件,如下:
~~~
AndroidStudioProjects/SecondNdkTest/ndklibrary/src/main$ javah -d jni -classpath ../../build/intermediates/classes/debug com.linc.ndklibrary.SecondLib
AndroidStudioProjects/SecondNdkTest/ndklibrary/src/main$ ls
AndroidManifest.xml java jni res
AndroidStudioProjects/SecondNdkTest/ndklibrary/src/main$ ls jni/
com_linc_ndklibrary_SecondLib.h
~~~
头文件内容如下:
~~~
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_linc_ndklibrary_SecondLib */
#ifndef _Included_com_linc_ndklibrary_SecondLib
#define _Included_com_linc_ndklibrary_SecondLib
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_linc_ndklibrary_SecondLib
* Method: intMethod
* Signature: ()[I
*/
JNIEXPORT jintArray JNICALL Java_com_linc_ndklibrary_SecondLib_intMethod
(JNIEnv *, jclass);
/*
* Class: com_linc_ndklibrary_SecondLib
* Method: stringMethod
* Signature: ()[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_com_linc_ndklibrary_SecondLib_stringMethod
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
~~~
## Native代码实现
在jni目录中新建c文件SecondLib.c与头文件对应,分别实现上述两个方法,内容如下:
~~~
#include "com_linc_ndklibrary_SecondLib.h"
const static int length=10;
//int array
JNIEXPORT jintArray JNICALL Java_com_linc_ndklibrary_SecondLib_intMethod
(JNIEnv *env, jclass obj)
{
jintArray array;
array=(*env)->NewIntArray(env,10);
int i=1;
for(;i<=10;++i)
{
(*env)->SetIntArrayRegion(env,array,i-1,1,&i);
}
//get array length
int len=(*env)->GetArrayLength(env,array);
//array content
jint* elems=(*env)->GetIntArrayElements(env,array,0);
return array;
}
//string array
JNIEXPORT jobjectArray JNICALL Java_com_linc_ndklibrary_SecondLib_stringMethod
(JNIEnv *env, jclass obj)
{
jclass class=(*env)->FindClass(env,"java/lang/String");
jobjectArray string=(*env)->NewObjectArray(env,(jsize)length,
class,0);
jstring jstr;
char* _char[]={"my ","name ","is ",
"linc!!","正在","学习",
"JNI","和","NDK","技术!"
};
int i=0;
for(;i<length;++i)
{
jstr=(*env)->NewStringUTF(env,_char[i]);
(*env)->SetObjectArrayElement(env,string,i,jstr);
}
return string;
}
~~~
## 编译
在local.properties中加入ndk路径:
~~~
ndk.dir=/opt/ndk/android-ndk-r10b
~~~
然后在ndklibrary的build.gradle中defaultConfig中加入ndk定义,如下:
~~~
defaultConfig {
minSdkVersion 15
targetSdkVersion 22
versionCode 1
versionName "1.0"
ndk{
moduleName "SecondLib"
}
}
~~~
这样就可以直接编译了,不用自己编写make文件了。
Build—>Make Module’ndklibrary’,生成的so如下:
~~~
AndroidStudioProjects/SecondNdkTest$ find -name *.so
./ndklibrary/build/intermediates/ndk/debug/lib/armeabi/libSecondLib.so
./ndklibrary/build/intermediates/ndk/debug/lib/armeabi-v7a/libSecondLib.so
./ndklibrary/build/intermediates/ndk/debug/lib/mips/libSecondLib.so
./ndklibrary/build/intermediates/ndk/debug/lib/x86/libSecondLib.so
./ndklibrary/build/intermediates/ndk/debug/obj/local/armeabi/libSecondLib.so
./ndklibrary/build/intermediates/ndk/debug/obj/local/armeabi-v7a/libSecondLib.so
./ndklibrary/build/intermediates/ndk/debug/obj/local/mips/libSecondLib.so
./ndklibrary/build/intermediates/ndk/debug/obj/local/x86/libSecondLib.so
~~~
注:
至于直接在Activity中用native的方法请参考下面的前两个链接。我遇到了问题没有得到解决:
~~~
$ javah -d jni -classpath /opt/sdk/platforms/android-5.1/android.jar;../../build/intermediates/classes/debug com.linc.secondndktest.MainActivity
Error: no classes specified
bash: ../../build/intermediates/classes/debug/: Is a directory
~~~
参考:
[http://blog.csdn.net/rznice/article/details/42295215](http://blog.csdn.net/rznice/article/details/42295215)
[http://blog.csdn.net/sodino/article/details/41946607](http://blog.csdn.net/sodino/article/details/41946607)
[http://stackoverflow.com/questions/10483959/javah-error-android-app-activity-not-found](http://stackoverflow.com/questions/10483959/javah-error-android-app-activity-not-found)
[http://blog.csdn.net/lincyang/article/details/6705143](http://blog.csdn.net/lincyang/article/details/6705143)
- 前言
- 一:文本与布局
- 二:组合控件
- 三:性能测试类
- 四:语音识别
- 五:读取Excel
- 六:PreferenceActivity使用详解
- 七:按钮控制ViewPager的左右翻页
- 八:Ubuntu下切换JDK版本
- 九:最新Android开发环境(Eclipse+ADT+Android 5.0)
- 十:获得屏幕物理尺寸、密度及分辨率
- 十一:Android Studio和Gradle
- 十二:Android Studio导入第三方类库、jar包和so库
- 十三:APK签名
- 十四:混淆与反编译
- 十五:多分辨率适配常用目录
- 十六:getprop与dumpsys命令
- 十七:Linux下的模拟器硬件加速
- 十八:adb取出安装在手机中的apk
- 十九:android studio导出jar包(Module)并获得手机信息
- 二十:两个开源的图表/报表控件
- 二十一:Android原型设计工具探索
- 二十二:Android 5.1 SDK下载与配置
- 二十三:Android Studio的NDK开发
- 二十四:横竖屏切换
- 二十五:模拟器如何重启?试试Genymotion!
- 二十六:persistableMode与Activity的持久化
- 二十七:Maven编译开源二维码扫描项目zxing