Я пытаюсь вернуть недавно созданный объект класса Java на нативном для Android.После возврата объекта я сталкиваюсь с падением, когда пытаюсь получить доступ к внутренним объектам возвращаемого объекта.
На данный момент я просто использую функцию NewObject (), затем устанавливаю параметры и затем возвращаюсь из родной (язык языка) функции.
Нужно ли использовать какую-либо другую функцию дляинформировать JVM, а также сделать этот объект сборщиком мусора?
Я загрузил весь проект (проект Eclipse) в eSnips здесь. Нажмите здесь для проекта Android .Чтобы вы могли загрузить и просмотреть свой код.
Объект класса 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