您的位置:首页 > 移动开发 > Android开发

android JNI学习之五 JNI中常用的方法

2013-07-24 11:53 453 查看
http://lipeng88213.iteye.com/blog/1292570

 

android JNI学习之五 JNI中常用的方法

参考:http://blog.csdn.net/fontlose/article/details/6600122
http://www.cnblogs.com/daniel-shen/archive/2006/10/16/530587.html
http://blog.csdn.net/yang_hui1986527/article/details/6887052
http://www.cnblogs.com/liangwind/archive/2009/08/26/1925511.html
http://www.cnblogs.com/luxiaofeng54/category/315742.html

Java代码







=============================================================================================================== 

//找到类文件 

jclass  objectClass = (*env)->FindClass(env, "com.lp.MailInfo"); 

//或者 obj 参数表示要你想要得到类型的类对象。
 
jclass class_Field = (*env)->GetObjectClass(env,obj);    
 
//得到构造函数 

jmethodID mid_date = (*env)->GetMethodID(env,objectClass,
"<init>", "()V"); 

//生成对象 

jobject o = (*env)->NewObject(env,jclass,jmethod); 
//jclass类 构造方法 后面的就是构造方法的参数  可以没有 
 
 
例如  
jobject     book;   
jclass      class_book;    
jmethodID  md_book;    
class_book = (*env)->FindClass(env,"LBook1;");    

md_book = (*env)->GetMethodID(env,class_book,"<init>","(IILjava/lang/String;)V");   

book = (*env)->NewObject(env,class_book,md_book,100,1,"huanghe");   

 
 
=============================================================================================================== 
http://www.cnblogs.com/daniel-shen/archive/2006/10/16/530587.html 
 
表 3-2 Java虚拟机类型签名  

类型签名 Java 类型 
Z boolean  

B byte 

C char 

S short 

I int 

J long 注意 这个是J 

F float 

D double 

L fully-qualified-class ; 全限定的类 

[type type[]  
(arg-types)ret-type 方法类型 
例如,Java 方法: 
    long fun(int n, String s,
int[] arr); 

具有以下类型签名: 
    (ILjava/lang/String;[I)J 
 
     
属性 
访问对象实例域的相关函数如下:  
jfieldID GetFieldID(JNIEnv *env, jclass cl, const
char name[],
const
char sig[]) 获取实例对象的域ID 

该函数返回一个域的标识符。各参数含义如下:  
env JNI 接口指针;cl 类对象 ; name 域名; sig 编码的域签名  
 
XXX GetXXXField(JNIEnv *env, jobject obj, jfieldID id)  
该函数返回域的值。域类型XXX是Object, Boolean, byte,
char ,
short,
int ,long ,float
double 中类型之一。  

参数 env JNI借口指针;obj为域所在对象;id为域的标识符。  
void SetXXXField(JNIEnv *env,jobject obj, jfieldID id, XXX value)  

 
例如: 
 
//招到类中名为"topic"的string类型的属性 

jfieldID topicFieldId = (*env)->GetFieldID(env, objectClass,"topic",
"Ljava/lang/String;"); 

jstring str = (*env)->GetStringField(env,obj,topicFieldId); 
jfieldID ival = (env)->GetFieldID(objectClass,"serial","I"); 

(env)->SetIntField(obj,ival,10); 

 
 
方法 
 
 
得到方法id 
static jmethodID message; 

static jmethodID audio; 

static jmethodID video; 

 
video = (*env)->GetMethodID(env,ljls,"video_data_cb","([BI)I");  

audio = (*env)->GetMethodID(env,ljls,"audio_data_cb","([BI)I");   

message = (*env)->GetMethodID(env,ljls,"message_cb","(SI)I"); 

 
调用方法 
int ret = (*env)->CallIntMethod(env,g_meida_obj,audio,jarray,size);  

env obj对象 方法id 参数 
 
静态方法 不推荐调用 
GetStaticMethodID 
 
 
=============================================================================================================== 

jbyteArray 转换为unsigned char

unsigned char *src; 

 
jbyte *arr = (*env)->GetByteArrayElements(env,yuvBuf,0); 

src = (char *)arr; 

 
unsigned char *转换为jbyteArray 

unsigned char *dst; 

jbyte *byte = (jbyte*)dst; 

jbyteArray rgbBuf = (*env)->NewByteArray(env,width*height*3); 

(*env)->SetByteArrayRegion(env,rgbBuf, 0, width*height*3,
byte); 

//释放 

(*env)->ReleaseByteArrayElements(env,yuvBuf,arr,0); 

 
=============================================================================================================== 

让object成为全局变量 
 
1、定义全局变量 
static jobject g_meida_obj; 

2、声明全局变量 
g_meida_obj = (*env)->NewGlobalRef(env,obj); 
 
貌似用jmethodID不需要特殊设置 直接定义复制即可 
 
=============================================================================================================== 

 
关于线程 
 
1、定义全局变量 
 
static JavaVM   *g_jvm; 

 
2、赋值 
 
(*env)->GetJavaVM(env,&g_jvm); 
 
3、你在需要用的地方 特别是不是jni的方法 要想使用当前线程的JNIEnv  

 
JNIEnv *env; 
(*g_jvm)->AttachCurrentThread(g_jvm,&env, NULL);  
。。。。。。 
(*g_jvm)->DetachCurrentThread(g_jvm); 
 
 
=============================================================================================================== 

回收内存 
 
jclass cls =  env->FindClass("sinashow1android/info/BlackIPUserInfo"); 

jobject black_ip_obj = env->NewObject(cls,construction_id); 
 
//回收局部对象的内存 

env->DeleteLocalRef(black_ip_obj); 
env->DeleteLocalRef(cls); 
 
线程处理是 需要放开 
(*g_jvm)->DetachCurrentThread(g_jvm); 
 
 
=============================================================================================================== 

char 转换为 string 

jstring chartojstring(JNIEnv *env, const
char *chars) 

    { 
        jstring result; 
        jint len = strlen(chars); 
        if(len <=
0) 
        { 
            result = env->NewStringUTF(""); 

            return result; 

        } 
 
        jclass stringClass; 
        jmethodID cid; 
        jbyteArray elemArr; 
        jstring jencoding; 
 
        stringClass = env->FindClass("java/lang/String"); 

        if (stringClass == NULL) { 

            return NULL;  

        } 
 
        cid = env->GetMethodID(stringClass,"<init>",
"([BLjava/lang/String;)V"); 

        if (cid == NULL) { 

            return NULL;  

        } 
 
        jencoding = env->NewStringUTF("GBK"); 

        elemArr = env->NewByteArray(len); 
        if (elemArr == NULL) { 

            return NULL;  

        } 
        env->SetByteArrayRegion(elemArr, 0, len, (jbyte*)chars); 

        result = (jstring)(env->NewObject(stringClass, cid, elemArr, jencoding)); 

        env->DeleteLocalRef(elemArr); 
        env->DeleteLocalRef(stringClass); 
        env->DeleteLocalRef(jencoding); 
        return result; 

    } 

===============================================================================================================
//找到类文件
jclass  objectClass = (*env)->FindClass(env, "com.lp.MailInfo");
//或者 obj 参数表示要你想要得到类型的类对象。
jclass class_Field = (*env)->GetObjectClass(env,obj);

//得到构造函数
jmethodID mid_date = (*env)->GetMethodID(env,objectClass, "<init>", "()V");
//生成对象
jobject o = (*env)->NewObject(env,jclass,jmethod);
//jclass类 构造方法 后面的就是构造方法的参数  可以没有

例如
jobject     book;
jclass      class_book;
jmethodID  md_book;
class_book = (*env)->FindClass(env,"LBook1;");
md_book = (*env)->GetMethodID(env,class_book,"<init>","(IILjava/lang/String;)V");
book = (*env)->NewObject(env,class_book,md_book,100,1,"huanghe");

=============================================================================================================== http://www.cnblogs.com/daniel-shen/archive/2006/10/16/530587.html 
表 3-2 Java虚拟机类型签名
类型签名 Java 类型
Z boolean
B byte
C char
S short
I int
J long 注意 这个是J
F float
D double
L fully-qualified-class ; 全限定的类
[type type[]
(arg-types)ret-type 方法类型
例如,Java 方法:
long fun(int n, String s, int[] arr);
具有以下类型签名:
(ILjava/lang/String;[I)J

属性
访问对象实例域的相关函数如下:
jfieldID GetFieldID(JNIEnv *env, jclass cl, const char name[], const char sig[]) 获取实例对象的域ID
该函数返回一个域的标识符。各参数含义如下:
env JNI 接口指针;cl 类对象 ; name 域名; sig 编码的域签名

XXX GetXXXField(JNIEnv *env, jobject obj, jfieldID id)
该函数返回域的值。域类型XXX是Object, Boolean, byte, char , short, int ,long ,float, double 中类型之一。
参数 env JNI借口指针;obj为域所在对象;id为域的标识符。
void SetXXXField(JNIEnv *env,jobject obj, jfieldID id, XXX value)

例如:

//招到类中名为"topic"的string类型的属性
jfieldID topicFieldId = (*env)->GetFieldID(env, objectClass,"topic", "Ljava/lang/String;");
jstring str = (*env)->GetStringField(env,obj,topicFieldId);
jfieldID ival = (env)->GetFieldID(objectClass,"serial","I");
(env)->SetIntField(obj,ival,10);

方法

得到方法id
static jmethodID message;
static jmethodID audio;
static jmethodID video;

video = (*env)->GetMethodID(env,ljls,"video_data_cb","([BI)I");
audio = (*env)->GetMethodID(env,ljls,"audio_data_cb","([BI)I");
message = (*env)->GetMethodID(env,ljls,"message_cb","(SI)I");

调用方法
int ret = (*env)->CallIntMethod(env,g_meida_obj,audio,jarray,size);
env obj对象 方法id 参数

静态方法 不推荐调用
GetStaticMethodID

===============================================================================================================
jbyteArray 转换为unsigned char *
unsigned char *src;

jbyte *arr = (*env)->GetByteArrayElements(env,yuvBuf,0);
src = (char *)arr;

unsigned char *转换为jbyteArray
unsigned char *dst;
jbyte *byte = (jbyte*)dst;
jbyteArray rgbBuf = (*env)->NewByteArray(env,width*height*3);
(*env)->SetByteArrayRegion(env,rgbBuf, 0, width*height*3, byte);
//释放
(*env)->ReleaseByteArrayElements(env,yuvBuf,arr,0);

===============================================================================================================
让object成为全局变量

1、定义全局变量
static jobject g_meida_obj;
2、声明全局变量
g_meida_obj = (*env)->NewGlobalRef(env,obj);

貌似用jmethodID不需要特殊设置 直接定义复制即可

===============================================================================================================

关于线程

1、定义全局变量

static JavaVM	*g_jvm;

2、赋值

(*env)->GetJavaVM(env,&g_jvm);

3、你在需要用的地方 特别是不是jni的方法 要想使用当前线程的JNIEnv

JNIEnv *env;
(*g_jvm)->AttachCurrentThread(g_jvm,&env, NULL);
。。。。。。
(*g_jvm)->DetachCurrentThread(g_jvm);

===============================================================================================================
回收内存

jclass cls =  env->FindClass("sinashow1android/info/BlackIPUserInfo");
jobject black_ip_obj = env->NewObject(cls,construction_id);

//回收局部对象的内存
env->DeleteLocalRef(black_ip_obj);
env->DeleteLocalRef(cls);

线程处理是 需要放开
(*g_jvm)->DetachCurrentThread(g_jvm);

===============================================================================================================
char 转换为 string
jstring chartojstring(JNIEnv *env, const char *chars)
{
jstring result;
jint len = strlen(chars);
if(len <= 0)
{
result = env->NewStringUTF("");
return result;
}

jclass stringClass;
jmethodID cid;
jbyteArray elemArr;
jstring jencoding;

stringClass = env->FindClass("java/lang/String");
if (stringClass == NULL) {
return NULL;
}

cid = env->GetMethodID(stringClass,"<init>", "([BLjava/lang/String;)V");
if (cid == NULL) {
return NULL;
}

jencoding = env->NewStringUTF("GBK");
elemArr = env->NewByteArray(len);
if (elemArr == NULL) {
return NULL;
}
env->SetByteArrayRegion(elemArr, 0, len, (jbyte*)chars);
result = (jstring)(env->NewObject(stringClass, cid, elemArr, jencoding));
env->DeleteLocalRef(elemArr);
env->DeleteLocalRef(stringClass);
env->DeleteLocalRef(jencoding);
return result;
}


数组的常用操作:



对象的常用操作:



另外

1、

Java代码






http://blog.csdn.net/yang_hui1986527/article/details/6887052 
http://blog.csdn.net/yang_hui1986527/article/details/6887052


这个里面 有JNI各个方法的说明  可以当做api

2、

Java代码







推荐一个网址 里面关于jni的学习内容比较多 

推荐一个网址 里面关于jni的学习内容比较多


http://blog.csdn.net/kangyaping/article/details/6584027
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: