这一节开始将,怎么将公司扔给你的c代码封装成android的so库呢.
1.给自己的c代码添加log
c代码中的log,在ndk开发中,他是不能直接打印到我们android studio中.
https://www.cnblogs.com/0616--ataozhijia/p/5628291.html根据这个来就可以了.
用法:
LOGE("a:%d,c:%c",a,b);
2.开始我们接口封装了.
<1.这个时候我要了解所有的jni函数
从简单开始.
先看如下java和本地类型,本地类型是说jni中的类型
Java 类型 | ||
boolean | ||
byte | ||
char | ||
short | ||
int | ||
long | ||
float | ||
double | ||
void |
类型签名 | |
Z | |
B | |
C | |
S | |
I | |
J | |
F | |
D | |
L fully-qualified-class ; | |
[ type |
注: 下面代码,我是.cpp的文件,所以不需要加env参数
jstring jstr = env->NewStringUTF("hhhh");
//可以将"hhhh"转换成jstring,或者将char* 转换成 jstring. 如果你想将字符串"hhhh",转换成jni识别的jstring的话可以这么转换.
constchar *str4 = env->GetStringChars(jstr,0);
//可以将jstring转换成char*,这是将jstring转换成c代码识别的char* 字符串. 这个一般用在将java代码传递字符串参数到c函数中,通过转换成c的字符串,供c使用.
const char*str = env->GetStringUTFChars(jstr,0);//可以将jstring 转换成 char* UTF格式
//可以将jstring转换成char*,这是将jstring转换成c代码识别的char* 字符串. 这个一般用在将java代码传递字符串参数到c函数中,通过转换成c的字符串,供c使用.
jsize lenth = env->GetStringLength(jstr);//获取jstring字符串的长度
//获取jstring的长度
jstring js = env->NewStringUTF(str);//将char*转换成jstring类型
可以将char*转成成jstring类型. 一般用来将c的char*类型转换成jstring类型,然后把jstring做为返回值 return jstring;
jclass jcls = env->FindClass("com/viking/jni2/JniCls1");//根据包名类名获取jclass
根据java中的包名和类名,获取jclass. jclass 有很多用途 ,比如说在c中创建java对象,获取java类中变量的id,获取Java类中方法的id,可以通过变量id,和方法id,创建Java对象,
获取java对象中变量的值,等等.
jclass jcls1 = env->GetObjectClass(jobj);//通过jobject 获取jclass
//根据java对象去获取这个对象的jclass类. 作用跟上面一样.这个也很重要.
jobject job = env->NewGlobalRef(jobj);//将局部引用变成全局引用
//将局部引用变成全局引用.不多解释.
env->DeleteGlobalRef(job); //删除全局引用
//删除全局引用,释放内存用的
env->DeleteLocalRef(job); //删除局部引用
//删除局部引用,释放内存用的
jmethodID jme = env->GetMethodID(jcls,"<init>","()V");
//根据jclass类和方法名,获取methodid方法id,也可以获取构造方法id,上面是构造方法的id,<init>表示构造方法, ()V 括号里面为构造方法需要的参数类型 ,V为返回值,
我这里没添加参数,无返回值的,如果要添加参数的话
如: "(Ljava/lang/String;ILcom/viking/Data;)V" 这个意思就是, public Method(String str,int i ,Data data){} 这样的构造方法.
获得构造方法id,我们就可以在jni代码中创建java对象了.
jobject j_jni_cls1_1 = env->NewObject(jcls, jme);//根据类和methodid获取对象
创建java对象, jcls:java类的jclass ,jme :java类的构造方法的id;具体代码如下
jclass jcls = env->FindClass("com/viking/Data");
jmethodID jme = env->GetMethodID(jcls,"<init>","()V");
jobject j_jni_cls1_1 = env->NewObject(jcls, jme);
jmethodID jeid = env->GetMethodID(jcls,"getName","()Ljava/lang/String;");//获取类的方法id
上面说了怎么获取构造方法id,那么获取其他方法id,也大同小异了.
jcls:类 getName:方法名 ()Ljava/lang/String; :方法的参数和返回值 类型,这里是没有参数, 返回值类型为string.
烦死,一言不和就复制代码了.
//创建两个对象TImageUserInfo TPicInfo jclass jimageuserinfobean = env->FindClass("com/viking/bean/TImageUserInfo"); jclass jpicinfobean = env->FindClass("com/viking/bean/TPicInfo"); //获取构造方法id jmethodID jimageuserinfobeanID = env->GetMethodID(jimageuserinfobean,"<init>","()V"); jmethodID jpicinfobeanID = env->GetMethodID(jpicinfobean,"<init>","()V"); //创建对象 jobject jimageuserinfo = env->NewObject(jimageuserinfobean,jimageuserinfobeanID); jobject jpicinfo = env->NewObject(jpicinfobean,jpicinfobeanID);
jclass intarrayclass = env->FindClass("[I"); //获得一维数组 的类引用,即jintArray类型
获取java数组对象的jclass类. 可用来创建数组对象.
jobjectArray jarr = env->NewObjectArray(5,intarrayclass,NULL);//获取数组的jclass,获取大小为五的,类型为jclass类型的,jobjectArray数组对象
算了,下节直接复制代码了. 每种实现都复制一段. 附讲解. 这样一点点敲,累死了.