以文本方式查看主题

-  曙海教育集团论坛  (http://peixun0.cn/bbs/index.asp)
--  Android应用开发  (http://peixun0.cn/bbs/list.asp?boardid=45)
----  Android学习开发4--Android在C++中调用java(3)  (http://peixun0.cn/bbs/dispbbs.asp?boardid=45&id=2037)

--  作者:wangxinxin
--  发布时间:2010-12-3 11:51:12
--  Android学习开发4--Android在C++中调用java(3)

5.2 java类的实例化
都知道java需要 obj var = new obj();这样一个过程,我们在C++中调用java类的成员函数,当然也要先示例话一个类。
示例化的函数如下所示
jobject getInstance(JNIEnv* env, jclass obj_class)
{
    jmethodID construction_id = env->GetMethodID(obj_class, "<init>", "()V");
    jobject obj = env->NewObject(obj_class, construction_id);
    return obj;
}
这个函数中的env表示环境参数,jclass表示一个java类的句柄。
jmethodID construction_id = env->GetMethodID(obj_class, "<init>", "()V");
GetMethodID的参数分别为(类句柄,方法名称,参数名称)
这个是为了获取java类中某个方法的句柄,有一点需要特别注意的,在获取构造方法的句柄和别的方法的句柄是不一样的。
获取一般方法的句柄所填写“方法名称”参数直接就是这个方法的名称,而构造函数的话就必须填写"<init>"。除了这点区别外,就没有区别了。
而我们的“参数名称”似乎写的就有些奇怪了。但是细说下他的规律也就不怪了。
参数名称的书写规则为 (参数1类型,参数2类型….)返回类型。而相应类型的表示如下所示
图片点击可在新窗口打开查看

比如我们要找个int func(double)类型的函数,就该这么写:
jmethodID construction_id = env->GetMethodID(obj_class, " func ", "(D)I");
找到了构造函数的方法之后我们直接调用构造函数,然后把生成的类返回即可
jobject obj = env->NewObject(obj_class, construction_id);
其中obj_class为类的句柄construction_id为构造函数的句柄,而类的实例被该函数返回。

5.3 调用java类的其他函数
JNIEXPORT jstring JNICALL Java_com_hm_hello_CActivityMain_stringFromJNI
(JNIEnv* env, jobject)
{
   jstring str;
   jclass java_class = env->FindClass("com/hm/hello/CForCall");
    if (java_class == 0)
    {
       return env->NewStringUTF("not find class!");
    }
   jobject java_obj = getInstance(env, java_class);
   if (java_obj == 0)
   {
       return env->NewStringUTF("not find java OBJ!");
   }
   jmethodID java_method = env->GetMethodID(java_class, "GetJavaString", "()Ljava/lang/String;");
   if(java_method == 0)
   {
       return env->NewStringUTF("not find java method!");
   }
   str = (jstring)env->CallObjectMethod(java_obj, java_method);
   return str;
}
看完了构造函数的介绍,这段代码其实很容易就看懂了,我们发现调用java中的函数的步骤无非几步:
1找到类句柄
2找到类的方法的句柄
3实例化类
4调用实例化类的方法。
而以上代码中只有一段没说过,就是
jclass java_class = env->FindClass("com/hm/hello/CForCall");
看名字就知道,是在找相应的类的句柄,其中com.hm.hello准备调用类的完整包名(把.转换为/),而CforCall就是我们要调用的类的名称。
至此,编译,然后在Android调试,可爱的机器人又出现了,哈哈,屏幕上显示出现了12345,成功!