android – 对NewObject调用的无效间接引用

前端之家收集整理的这篇文章主要介绍了android – 对NewObject调用的无效间接引用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
好的,所以我有下面的本机代码.
我试图从它返回一个FilePermissionInfo数组,填充stat()返回的一些数据.
问题是第一次调用NewObject时出现以下错误

06-15 20:25:17.621: W/dalvikvm(2287): Invalid indirect reference
0x40005820 in decodeIndirectRef 06-15 20:25:17.621: E/dalvikvm(2287):
VM aborting

这很奇怪,因为我唯一的参考对象是jclass(对于FilePermissionInfo),我把它变成了一个全局引用.

代码是:

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,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,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,rawString);
    LOGI("xxx3");
}

(*env)->DeleteLocalRef(env,filePermInfoCls);

return result;

}

Java类构造函数签名和路径是:

const char* kFilePermissionInfoPath = "com/mn/rootscape/utils/FilePermissionInfo";
const char* kFilePermInfoConstructorSig = "(JJJJJJJJLjava/lang/String;Ljava/lang/String;ZLjava/lang/String;)V";

请注意,如果我在默认构造函数调用NewObject,那么它可以正常工作.

解决方法

好的,找到了.
这是jstring参数的问题.事实证明,你不能将空字符串(或者甚至是NULL)作为jstring传递.
相反,我使用(* env) – > NewStringUTF(env,NULL)来创建NULL jstring.

好像现在好了.

由于这个问题产生了一定程度的高活动,我将在下面发布最终解决方案.请注意,nullString变量在其作用域的末尾(或者当您使用它时)被释放:

jstring nullString = (*env)->NewStringUTF(env,NULL);
...
        jobject permInfo = (*env)->NewObject(env,(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,(jboolean)1,nullString);
...
       (*env)->DeleteLocalRef(env,nullString);

猜你在找的Android相关文章