2011-12-30 55 views
1

我想返回一个新创建的java类对象,原生android。当我试图访问返回对象的内部对象时,返回对象时,我面临崩溃。如何返回本地新创建的java类对象到java android?

截至目前,我只是使用NewObject()函数,然后设置参数,然后从本地(c语言)函数返回。

我是否需要使用任何其他函数来通知JVM并且还要使垃圾收集?

我已经在eSnips这里上传了整个项目(Eclipse项目)。 Click here for the android project。所以你可以下载并查看你的代码。

DataObject2.java类对象将从本机返回。

UserDefinedObj.java是

package example.nativeobj.obj; 

public class UserDefinedObj { 
    public int intPrimitive; 

    @Override 
    public String toString() { 
     StringBuffer strBuf = new StringBuffer(); 

     strBuf.append("UserDefinedObj.intPrimitive: "); 
     strBuf.append(intPrimitive); 

     return strBuf.toString(); 
    } 
} 

当DataObject2.java是

package example.nativeobj.obj; 

public class DataObject2 { 
    public int intData; 
    public String strData; 
    public UserDefinedObj usrDefData; 

    @Override 
    public String toString() { 
     StringBuffer strBuf = new StringBuffer(); 

     strBuf.append("\n DataObject2.intData: "); 
     strBuf.append(intData); 
     strBuf.append("\n DataObject2.strData: "); 
     strBuf.append(strData); 
     strBuf.append("\n DataObject2.usrDefData: "); 
     strBuf.append(usrDefData); 
//  strBuf.append("\n UserDefinedObj.intPrimitive: "); 
//  strBuf.append(usrDefData.intPrimitive); 

     return strBuf.toString(); 
    } 
} 

我对着崩溃问题。

但当DataObject.java是

package example.nativeobj.obj; 

public class DataObject2 { 
    public int intData; 
    public String strData; 
    public UserDefinedObj usrDefData; 

    @Override 
    public String toString() { 
     StringBuffer strBuf = new StringBuffer(); 

     strBuf.append("\n DataObject2.intData: "); 
     strBuf.append(intData); 
     strBuf.append("\n DataObject2.strData: "); 
     strBuf.append(strData); 
     strBuf.append("\n DataObject2.usrDefData: "); 
//  strBuf.append(usrDefData); 
     strBuf.append("\n UserDefinedObj.intPrimitive: "); 
     strBuf.append(usrDefData.intPrimitive); 

     return strBuf.toString(); 
    } 
} 

我不是朝向碰撞问题。

区别在于下面提到的这部分代码中,请注意。

//  strBuf.append(usrDefData); 
     strBuf.append("\n UserDefinedObj.intPrimitive: "); 
     strBuf.append(usrDefData.intPrimitive); 

 strBuf.append(usrDefData); 
//  strBuf.append("\n UserDefinedObj.intPrimitive: "); 
//  strBuf.append(usrDefData.intPrimitive); 

会有人请让我知道在我的代码中的错误。

这是我的原生代码:

/* DO NOT EDIT THIS FILE - it is machine generated */ 
#include <jni.h> 
/* Header for class example_nativeobj_api_Native */ 

#include "custom_debug.h" 

//Paths 
static const char *gDataObject1ClassPath = "example/nativeobj/obj/DataObject1"; 
static const char *gDataObject2ClassPath = "example/nativeobj/obj/DataObject2"; 
static const char *gUserDefinedObjectClassPath = "example/nativeobj/obj/UserDefinedObj"; 

/* 
* Class:  example_nativeobj_api_Native 
* Method: func 
* Signature: (Lexample/nativeobj/obj/DataObject1;)Lexample/nativeobj/obj/DataObject2; 
*/ 
JNIEXPORT jobject JNICALL Java_example_nativeobj_api_Native_func 
    (JNIEnv *env, jclass cls, jobject dataobj1) { 

    jobject dataObject2Obj = NULL; 

    /* Get a reference to obj’s class */ 
    jclass dataObject1Cls = (*env)->GetObjectClass(env, dataobj1); 
    jclass dataObject2Cls = (*env)->FindClass(env, gDataObject2ClassPath); 
    jclass userDefinedObjCls = (*env)->FindClass(env, gUserDefinedObjectClassPath); 

    DBG_LOG_INFO("func: clazz references of the dataObject1Cls: %u, dataObject2Cls: %u, userDefinedObjCls: %u", 
        dataObject1Cls, dataObject2Cls, userDefinedObjCls); 
    if(dataObject1Cls == NULL || dataObject2Cls == NULL || userDefinedObjCls == NULL) { 
     ERROR_LOG_INFO("func: Unable to get the clazz references of the dataObject1Cls: %u, dataObject2Cls: %u, userDefinedObjCls: %u", 
       dataObject1Cls, dataObject2Cls, userDefinedObjCls); 
    } 

    //Get the field id of the User defined object class 
    jfieldID userDefObjintFid; 
    userDefObjintFid = (*env)->GetFieldID(env, userDefinedObjCls, "intPrimitive", "I"); 
    if (userDefObjintFid == NULL) { 
     ERROR_LOG_INFO("func: Unable to get the intData of the userDefinedObjCls"); 
     return NULL; /* failed to find the field */ 
    } 



    //Get the data from the dataobject1 class 
    ////Get the object class 
    jfieldID dataObj1IntFid; /* store the field ID */ 
    jfieldID dataObj1StrFid; 
    jfieldID dataObj1UsrDefObjFid; 

    jstring jstrDataObj1 = NULL; 
    const char *strDataObj1 = NULL; 
    jobject userDefObj = NULL; 
    jint iData1ObjInt = 0; 
    jint iUsrDefObjInt = 0; 

    jthrowable exc; 

    /* Look for the instance field s in cls */ 
    dataObj1IntFid = (*env)->GetFieldID(env, dataObject1Cls, "intData", "I"); 
    if (dataObj1IntFid == NULL) { 
     ERROR_LOG_INFO("func: Unable to get the intData of the dataObject1Cls"); 
     return NULL; /* failed to find the field */ 
    } 

    dataObj1StrFid = (*env)->GetFieldID(env, dataObject1Cls, "strData", "Ljava/lang/String;"); 
    if (dataObj1StrFid == NULL) { 
     ERROR_LOG_INFO("func: Unable to get the strData of the dataObject1Cls"); 
     return NULL; /* failed to find the field */ 
    } 

    dataObj1UsrDefObjFid = (*env)->GetFieldID(env, dataObject1Cls, "usrDefData", "Lexample/nativeobj/obj/UserDefinedObj;"); 
    if (dataObj1UsrDefObjFid == NULL) { 
     ERROR_LOG_INFO("func: Unable to get the usrDefData of the dataObject1Cls"); 
     return NULL; /* failed to find the field */ 
    } 

    ////Get the values of the data members 
    iData1ObjInt = (*env)->GetIntField(env, dataobj1, dataObj1IntFid); 
    DBG_LOG_INFO("func: iData1ObjInt: %d", iData1ObjInt); 

    jstrDataObj1 = (*env)->GetObjectField(env, dataobj1, dataObj1StrFid); 
    strDataObj1 = (*env)->GetStringUTFChars(env, jstrDataObj1, NULL); 
    if (strDataObj1 == NULL) { 
     ERROR_LOG_INFO("func: Unable to get the string of dataObject1Cls"); 
     return NULL; 
    } 
    DBG_LOG_INFO("func: c.s = \"%s\"\n", strDataObj1); 

    ////Get the user defined object here 
    userDefObj = (*env)->GetObjectField(env, dataobj1, dataObj1UsrDefObjFid); 
    if(userDefObj == NULL) { 
     ERROR_LOG_INFO("func: Unable to get the userDefObj from dataObject1Cls"); 
     goto cleanup1; 
    } 

    //////Get the data memebers of the user define object 
    iUsrDefObjInt = (*env)->GetIntField(env, userDefObj, userDefObjintFid); 
    DBG_LOG_INFO("func: iUsrDefObjInt: %d", iUsrDefObjInt); 

    //Creating the new dataobject2 for returning from the function 
    ////Get the method id for the constructor of the class 
    jmethodID constructorId = (*env)->GetMethodID(env, dataObject2Cls, "<init>", "()V"); 
    if(constructorId == NULL) { 
     ERROR_LOG_INFO("func: Unable to get the constructor for the dataObject2Cls"); 
     goto cleanup1; 
    } 

    ////Creating the new object for the class 
    dataObject2Obj = (*env)->NewObject(env, dataObject2Cls, constructorId); 
    if(dataObject2Obj == NULL) { 
     ERROR_LOG_INFO("func: Unable to create an object for the class dataObject2Cls"); 
     exc = (*env)->ExceptionOccurred(env); 
     if (exc) { 
      /* We don't do much with the exception, except that 
      we print a debug message for it, clear it, and 
      throw a new exception. */ 
      (*env)->ExceptionDescribe(env); 

     } 
     goto cleanup1; 
    } 


    //Create the new dataobject2 
    ////Get the field id's of the objectdata2 members 
    jfieldID dataObj2IntFid; /* store the field ID */ 
    jfieldID dataObj2StrFid; 
    jfieldID dataObj2UsrDefObjFid; 

    dataObj2IntFid = (*env)->GetFieldID(env, dataObject2Cls, "intData", "I"); 
    if (dataObj2IntFid == NULL) { 
     ERROR_LOG_INFO("func: Unable to get the intData of the dataObject2Cls"); 
     goto cleanup1; /* failed to find the field */ 
    } 

    dataObj2StrFid = (*env)->GetFieldID(env, dataObject2Cls, "strData", "Ljava/lang/String;"); 
    if (dataObj2StrFid == NULL) { 
     ERROR_LOG_INFO("func: Unable to get the strData of the dataObject2Cls"); 
     goto cleanup1; /* failed to find the field */ 
    } 

    dataObj2UsrDefObjFid = (*env)->GetFieldID(env, dataObject2Cls, "usrDefData", "Lexample/nativeobj/obj/UserDefinedObj;"); 
    if (dataObj2UsrDefObjFid == NULL) { 
     ERROR_LOG_INFO("func: Unable to get the usrDefData of the dataObject2Cls"); 
     goto cleanup1; /* failed to find the field */ 
    } 

    ////Set the data member values 
    //////Set the int field 
    (*env)->SetIntField(env, dataObject2Obj, dataObj2IntFid, (iData1ObjInt+1)); 
    //////Set the string field 
    jstring jstr_temp = (*env)->NewStringUTF(env, strDataObj1); 
    if (jstr_temp == NULL) { 
     ERROR_LOG_INFO("func: Unable to create the new string utf for the dataobj2class object"); 
     goto cleanup1; /* out of memory */ 
    } 
    (*env)->SetObjectField(env, dataObject2Obj, dataObj2StrFid, jstr_temp); 
    //////Set teh user define object 
    ////////Get the method id for the constructor of the user defined class 
    jmethodID usrDefConstructorId = (*env)->GetMethodID(env, userDefinedObjCls, "<init>", "()V"); 
    if(usrDefConstructorId == NULL) { 
     ERROR_LOG_INFO("func: Unable to get the constructor for the dataObject2Cls"); 
     goto cleanup1; 
    } 

    ////////Creating the new object for the class 
    jobject userDefObject = (*env)->NewObject(env, dataObject2Cls, usrDefConstructorId); 
    if(!userDefObject) { 
     ERROR_LOG_INFO("func: Unable to create an object for the class userDefObject"); 
     goto cleanup1; 
    } 
    DBG_LOG_INFO("func: userDefObject: %u", userDefObject); 
    DBG_LOG_INFO("func: userDefObjintFid: %u", userDefObjintFid); 
    DBG_LOG_INFO("func: dataObj2UsrDefObjFid: %u", dataObj2UsrDefObjFid); 

    iUsrDefObjInt += 1; 
    DBG_LOG_INFO("func: iUsrDefObjInt: %d", iUsrDefObjInt); 
    (*env)->SetIntField(env, userDefObject, userDefObjintFid, iUsrDefObjInt); 
    ////////Set this user defined object in the data object 2 class 
    (*env)->SetObjectField(env, dataObject2Obj, dataObj2UsrDefObjFid, userDefObject); 

    ////////////////////////////////////////////////////////////////////////// 
    //For verifying if the user defined object is set 
// jobject userDefObj_Temp = (*env)->GetObjectField(env, dataObject2Obj, dataObj2UsrDefObjFid); 
// if(userDefObj == NULL) { 
//  ERROR_LOG_INFO("func: Unable to get the userDefObj from dataObject1Cls"); 
//  goto cleanup1; 
// } 
// 
// //////Get the data memebers of the user define object 
// int iUsrDefObjInt_temp = (*env)->GetIntField(env, userDefObj_Temp, userDefObjintFid); 
// DBG_LOG_INFO("func: iUsrDefObjInt_temp: %d", iUsrDefObjInt_temp); 

    ////////////////////////////////////////////////////////////////////////// 



    cleanup1: 
    //Release all the handlers 
    (*env)->ReleaseStringUTFChars(env, jstrDataObj1, strDataObj1); 


    //return the dataobject 2 
    return dataObject2Obj; 
} 


JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { 

    JNIEnv *env = NULL; 

    DBG_LOG_INFO("JNI_OnLoad: Called in libobjnative.so....."); 

    if((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK) { 
     ERROR_LOG_INFO("JNI_OnLoad: Failed to get the environment ising GetEnv"); 
     return -1; 
    } 


    return JNI_VERSION_1_4; 
} 


JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *jvm, void *reserved) { 

    DBG_LOG_INFO("JNI_OnUnload: Called in libobjnative.so....."); 

    return; 
} 

感谢&问候,
SSuman185

回答

0

发现问题。

这是在创建UserDefinedObj

的对象

在本地代码我在做这样的

jobject userDefObject = (*env)->NewObject(env, dataObject2Cls, usrDefConstructorId); 

当时提供的“dataObject2Cls”的参考,为“UserDefinedObj”

问题

了固定于提供 “userDefinedObjCls”

jobject userDefObject = (*env)->NewObject(env, userDefinedObjCls, usrDefConstructorId); 

Regards,
SSuman185