NDK简介
一、ndk简介:
c/c++的动态库。dalvik通过jni编程方式调用c/c++代码。
ndk编程提高软件性能,加密保护apk文件
ndk-build ndk编译生成脚本
java编译时会根据java声明文件生成dex文件,即使没有java代码
ndk共享库:ndk生成的 .so文件(类似dll)
ndk静态库:.a文件件
二、jni中的数据类型:
数据分两大类:基本类型,引用类型
基本类型
java类型 |
jni类型 |
c/c++类型 |
大小 |
boolean |
jboolean |
unsigned char |
无符号8位 |
byte |
jbyte |
char |
有符号8位 |
char |
jchar |
unsigned short |
无符号16位 |
short |
jshort |
short |
有符号16位 |
int |
jint |
int |
有符号32位 |
long |
jlong |
long long |
有符号64位 |
float |
jfloat |
float |
32位浮点数 |
double |
jdouble |
double |
64位浮点数 |
引用类型
java类型 |
原生类型 |
描述 |
java.lang.class |
jclass |
类类型 |
java.lang.throwable |
jthrowable |
异常类型 |
java.lang.string |
jstring |
字符类型 |
java.lang.object[] |
jobjectarray |
任意java对象数组 |
boolean[] |
jbooleanarray |
布尔型数组 |
byte[] |
jbytearray |
比特型数组 |
char[] |
jchararray |
字符型数组 |
short[] |
jshortarray |
短整型数组 |
int[] |
jintarray |
整型数组 |
long[] |
jlongarray |
长整型数组 |
float[] |
jfloatarray |
浮点型数组 |
double[] |
jdoublearray |
双浮点型数组 |
三、jni中对java类、域、方法的描述符
1。域描述:基本类型,引用类型,数组类型
基本类型描述符
域描述符 |
java语言类型 |
z |
boolean |
b |
byte |
c |
char |
s |
short |
i |
int |
j |
long |
f |
float |
d |
double |
引用描述符:l+类描述+;
eg:string ljava/lang/string;
object[] [ljava/lang/object;
数组域的描述符
eg:int[] [i
float[] [f
string[] [ljava/lang/string;
int[][] [[i
2。类描述符:类的完整名(包名+类名)“.”替换成“/”
eg:java.lang.string :java/lang/string
3。方法描述符:
规则:参数的域描述符按照声明顺序放入一个括号中,后跟返回值类型的域描述符。没有返回值用v(void)表示,如果是类引用后面加“;”
eg:string text() ()ljava/lang/string;
int fun(int i,object object) (iljava/lang/object;)i
void set(byte[] bytes) ([b)v
native中字符串的转换
1。c-〉java
jstring newstringutf(jnienv *env, // jni接口指针
const char* bytes)// c字符串
eg:jstring jstring1 = env->newstringutf(“hello wrold”);
2。java-〉c
char* getstringutfchars(jnienv *env, // jni接口指针
jstring string, // jstring java字符串
jboolean* iscopy) // 表示返回副本还是堆中固定值
eg:jboolean iscopy;
char* ch = env->getstringutfchars(jstring1,&iscopy);
native中创建数组
1。创建一维数组
// 创建
jintarray newintarray(jnienv *env, // jni接口指针
jsize length);// 数组长度
// 赋值数组某一范围
void setintarrayregion(jnienv *env, //jni接口指针
jintarray array, //目的数组
jsize start, //基本类型数组开始的位置
jsize len, //数组长度
const jint* buf); //源数组
// 获取数组值
void getintarrayregion(jnienv *env, //jni接口指针
jintarray array, //目的数组
jsize start, //基本类型数组开始的位置
jsize len, //数组长度
const jint* buf); //源数组
// 释放局部数组对象
void deletelocalref(jnienv *env, // jni接口指针
jobject localref) // 要释放的局部数组对象
用于构建其他基本数据类型的数组
new<primitivetype>array 方法族
set< primitivetype >arrayregion
get< primitivetype >arrayregion
2。创建数组对象
// 创建
jobjectarray newintarray(jnienv *env, // jni接口指针
length,// 数组长度
jcalss elementclass,// 类型
jobject initialelement)// 初始值
// 设置
void setobjectarrayelement(jnienv *env, //jni接口指针
jobjectarray array, //目的数组
jsize index, //目的数组的第几个索引
jobject value) //写入的值
native中java操作java类中的属性
1。java层非静态
获取java层中属性id
jfieldid getfieldid(jnienv *env, // jni接口指针
jclass class, // java类对象
const char *name,// 该属性的name名称
const char *sig): // 属性的域签名
获取java层中属性值
nativetype get<type>field(jnienv *env, // jni接口指针
jobject obj, // java 对象(不能null)
jfieldid fieldid);// 有效的域id
设置java层类中属性的值
void set<type>field(jnienv *env, // jni接口指针
jobject obj, // java 对象(不能null)
jfieldid fieldid,// 有效的域id
nativetype value);// 设置新值
2。java层静态
获取java层中属性id
jfieldid getstaticfieldid(jnienv *env, // jni接口指针
jclass class, // java类对象
const char *name,// 该属性的name名称
const char *sig): // 属性的域签名
获取java层中属性值
nativetype getstatic<type>field(jnienv *env, // jni接口指针
jobject obj, // java 对象(不能null)
jfieldid fieldid);// 有效的域id
设置java层类中属性的值
void setstatic<type>field(jnienv *env, // jni接口指针
jobject obj, // java 对象(不能null)
jfieldid fieldid,// 有效的域id
nativetype value);// 设置新值
native中操作java层类或接口的方法
1。java层静态方法:
获取java层中属性id
jmethodid getmethodid(jnienv *env, // jni接口指针
jclass class, // java类对象
const char *name,// 该属性的name名称
const char *sig): // 属性的域签名
获取java层中属性值
nativetype call<type>mothod(jnienv *env, // jni接口指针
jobject obj, // java 对象(不能null)
jmethodid jmethodid,// 方法id
...);// 要调用方法的参数
2。java层静态方法操作
获取java层中属性id
jmethodid getstaticmethodid(jnienv *env, // jni接口指针
jclass class, // java类对象
const char *name,// 该属性的name名称
const char *sig): // 属性的域签名
获取java层中属性值
nativetype callstatic<type>mothod(jnienv *env, // jni接口指针
jobject obj, // java 对象(不能null)
jmethodid jmethodid,// 方法id
...);// 要调用方法的参数
动态注册native方法
1。在java层声明要导出的函数
public native string getnatviestring();
2。在native中编写普通方法
3。定义数组在该数组中将java中声明方法和native中定义的方法进行邦定
4。在jni初始化函数jni_onload中注册函数
jint jni_onload(javavm *vm,void* reserved)
{
// 1。获取env对象
getenv或者attachcurrentthread
// 2。获取class
findclass
// 3。注册
registernatives()
// 4。返回jni版本
return jni_version_xx;
}
ndk调试器两款:
1。gdb:unix/linux下基于命令行的调试工具
2。lldb:基于llvm框架。
上一篇: UIView设置阴影