gpt4 book ai didi

Android JNI ReleaseByteArrayElements 不起作用

转载 作者:行者123 更新时间:2023-11-29 20:22:05 33 4
gpt4 key购买 nike

我在使用 Android JNI 时遇到了问题。我从 native C 调用一个 java 方法。一切正常,但几秒钟后应用程序崩溃,因为 JNI refs 的最大 512 个条目已满(或内存已满)。

这是我的代码:

int jniBluetoothSend( TJNIAdapter *pAdapter, byte *data, int dwLength )
{
JNIEnv *pEnv;
JavaVM *pVm = NULL;
jclass cls;
jmethodID methodId;
int nRet;
jbyteArray aData;

if ( pAdapter )
{
pVm = pAdapter->pVm;
( *pVm )->AttachCurrentThread( pVm, &pEnv, NULL );

if ( pAdapter->pClasses != NULL && pAdapter->pClasses->hgs_bluetooth != NULL )
{
// get function
methodId = ( *pEnv )->GetMethodID( pEnv, pAdapter->pClasses->hgs_bluetooth, "write", "([BI)I" );
if ( methodId )
{
aData = ( *pEnv )->NewByteArray( pEnv, dwLength);
( *pEnv )->SetByteArrayRegion( pEnv, aData, 0, dwLength, data);
// write Data to device
nRet = ( *pEnv )->CallIntMethod( pEnv, g_hgsBthObject, methodId, aData, dwLength );

// and delete Reference -> so GC can cleanup
( *pEnv )->DeleteLocalRef( pEnv, aData );
}
}
//( *pVm )->DetachCurrentThread( pVm ); -> // crashes as soon as getting called
}
return nRet;

每次调用“ReleaseByteArrayElements()”时,都会在 dalvik 的 Android 日志中显示一条警告:

JNI: unpinPrimitiveArray(0x428e84a8) failed to find entry (valid=1)

所以,我认为,问题是创建的数组没有被释放。但我不知道如何以正确的方式做到这一点。

谁能帮我解决这个问题?谢谢!

编辑

我做了几个测试。如果我将 DetachCurrentThread 函数添加到第二个 if() 的底部,如果 DetachCurrentThread 被调用,APP 就会崩溃。

但是我在另外一个函数中添加了DeleteLocalRef,APP就不会崩溃了。

所以我的问题是:我是否必须在我调用 AttachCurrentThread 的每个函数中调用 DetachCurrentThread 或者如果我调用一次到 APP 结束就足够了吗?

还更新了代码

最佳答案

Everytime ReleaseByteArrayElements() gets called a warning shows up in Android Log from dalvik:

JNI: unpinPrimitiveArray(0x428e84a8) failed to find entry (valid=1)

ReleaseByteArrayElements旨在与先前对 GetByteArrayElements 的调用配对.来自 Oracle's documentation :

Release<PrimitiveType>ArrayElements Routines
void Release<PrimitiveType>ArrayElements(JNIEnv *env,
ArrayType array, NativeType *elems, jint mode);

A family of functions that informs the VM that the native code no longer needs access to elems. The elems argument is a pointer derived from array using the corresponding Get<PrimitiveType>ArrayElements() function.

因为你没有调用 GetByteArrayElements你也不应该调用ReleaseByteArrayElements .

请注意 SetByteArrayRegion()函数不是固定数组的函数之一,因此不需要发布。

关于Android JNI ReleaseByteArrayElements 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33020494/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com