Referencia indirecta no válida en la llamada NewObject
Aceptar, así que tengo el código nativo a continuación. Estoy tratando de devolver una matriz de FilePermissionInfo de ella, rellenado con algunos datos devueltos por stat (). El problema es que consigo el error siguiente cuando NewObject se llama la primera vez:
06-15 20: 25: 17.621: W / dalvikvm (2287): Referencia indirecta no válida 0x40005820 en decodeIndirectRef 06-15 20: 25: 17.621: E / dalvikvm (2287): VM aborting
- Android: ¿puede obtener código nativo la intención de difusión del sistema android?
- ¿Cómo puede el código nativo de Android dirigirse a múltiples tipos de procesadores?
- ¿Cómo crear callbacks entre código androide y código nativo?
- Cómo depurar código nativo puro en android?
- ¿Cómo obtener la frecuencia de muestreo y la frecuencia del archivo de música (MP3) en android?
Es extraño, porque el único objeto de referencia que tengo es el jclass (para FilePermissionInfo) y lo convierto en una referencia global.
El código es:
JNIEXPORT jobjectArray JNICALL Java_com_mn_rootscape_utils_NativeMethods_getFilesPermissions( JNIEnv* env, jobject thizz, jobjectArray filePathsArray ) { jobjectArray result; int size = (*env)->GetArrayLength(env, filePathsArray); jboolean isCopy; jclass filePermInfoCls = (*env)->FindClass(env, kFilePermissionInfoPath); if(!filePermInfoCls) { LOGE("getFilesPermissions: failed to get class reference."); return NULL; } gFilePermInfoClass = (jclass)(*env)->NewGlobalRef(env, filePermInfoCls); LOGI("got gFilePermInfoClass"); jmethodID filePermInfoClsConstructor = (*env)->GetMethodID(env, gFilePermInfoClass, "<init>", kFilePermInfoConstructorSig); if(!filePermInfoClsConstructor) { LOGE("getFilesPermissions: failed to get method reference."); return NULL; } struct stat sb; LOGI("starting..."); result = (jobjectArray)(*env)->NewObjectArray(env, size, gFilePermInfoClass, NULL); for(int i = 0; i != size; ++i) { jstring string = (jstring) (*env)->GetObjectArrayElement(env, filePathsArray, i); const char *rawString = (*env)->GetStringUTFChars(env, string, &isCopy); if(stat(rawString, &sb) == -1) { LOGE("stat error for: %s", rawString); } LOGI("%ld %ld %ld %ld %ld %ld %ld %ld", sb.st_dev, sb.st_mode, sb.st_nlink, sb.st_uid, sb.st_gid, sb.st_atime, sb.st_mtime, sb.st_ctime); jobject permInfo = (*env)->NewObject(env, gFilePermInfoClass, filePermInfoClsConstructor, (long)sb.st_dev, (long)sb.st_mode, (long)sb.st_nlink, (long)sb.st_uid, (long)sb.st_gid, (long)sb.st_atime, (long)sb.st_mtime, (long)sb.st_ctime, "", "", 1, ""); LOGI("xxx1"); (*env)->SetObjectArrayElement(env, result, i, permInfo); LOGI("xxx2"); (*env)->ReleaseStringUTFChars(env, string, rawString); LOGI("xxx3"); } (*env)->DeleteLocalRef(env, filePermInfoCls); return result;
}
La firma y la ruta del constructor de la clase Java son:
const char* kFilePermissionInfoPath = "com/mn/rootscape/utils/FilePermissionInfo"; const char* kFilePermInfoConstructorSig = "(JJJJJJJJLjava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V";
Tenga en cuenta que si llamo a NewObject en el constructor predeterminado, entonces funciona bien.
- Android NDK: ¿Cómo anular onBackPressed en NativeActivity sin java?
- Comunicación entre webview y código nativo en una aplicación para móviles
- Android NativeActivity
- El impacto del código nativo en el desarrollo de aplicaciones para Android / iPhone
- ¿Cómo utilizar el código ARM Assembly en un proyecto de Android?
- ¿Cómo utilizar Valgrind con la aplicación android en Eclipse en Ubuntu para encontrar fugas de memoria de código nativo android en tiempo de ejecución?
- Cómo cambiar el archivo de salida de un mediarecorder sin detener el mediarecorder
- Error de aplicación con Android 4.0 o versiones posteriores
OK, lo encontré. Fue un problema con los parámetros jstring
. Resulta que no puedes pasar cadenas vacías (ni siquiera NULL para esa materia) como jstring
. En su lugar usé (*env)->NewStringUTF(env, NULL)
para crear un jstring
NULL.
Parece que funciona bien ahora.
Dado que esta pregunta generó algo de una actividad alta, estoy publicando la solución final a continuación. Tenga en cuenta que la variable nullString
se desasigna al final de su ámbito (o cuando haya terminado de usarlo):
jstring nullString = (*env)->NewStringUTF(env, NULL); ... jobject permInfo = (*env)->NewObject(env, gFilePermInfoClass, filePermInfoClsConstructor, (jbyte)permsOwner, (jbyte)permsGroup, (jbyte)permsOthers, (jlong)sb.st_uid, (jlong)sb.st_gid, (jlong)sb.st_atime, (jlong)sb.st_mtime, (jlong)sb.st_ctime, nullString, nullString, (jboolean)1, nullString); ... (*env)->DeleteLocalRef(env, nullString);
- ¿Es la mejor práctica para la navegación con pestañas?
- ¿Qué permisos se pueden conceder a los dispositivos enraizados?