Summary
PreviewPrepareStream / PreviewPrepareTest create a JNI global reference for jIFrameCallback and pass it to setFrameCallback. That reference is not reliably released when the same callback is registered again, or when the UVCPreview instance is replaced/destroyed. Repeated prepare can grow the JNI global reference table.
Location
app/src/main/cpp/libUvc_Support/uvc_support.cpp
Java_humer_UvcCamera_StartIsoStreamActivityUvc_PreviewPrepareStream
Java_humer_UvcCamera_SetUpTheUsbDeviceUvc_PreviewPrepareTest
app/src/main/cpp/libUvc_Support/UVC_Camera_Saki/UVCPreview.cpp
UVCPreview::setFrameCallback
UVCPreview::~UVCPreview
create_UVCPreview
Details
Both JNI entry points do:
jobject frame_callback_obj = env->NewGlobalRef(jIFrameCallback);
result = setFrameCallback(..., frame_callback_obj, ...);
UVCPreview::setFrameCallback only takes ownership when the new object is not the same as mFrameCallbackObj:
if (!env->IsSameObject(mFrameCallbackObj, frame_callback_obj)) {
if (mFrameCallbackObj)
env->DeleteGlobalRef(mFrameCallbackObj);
mFrameCallbackObj = frame_callback_obj;
// ...
}
IsSameObject compares the Java objects, not the JNI handles. Calling prepare again with the same IFrameCallback creates a new global ref. That branch is skipped, so the new ref is neither stored nor DeleteGlobalRef'd.
~UVCPreview() never calls DeleteGlobalRef(mFrameCallbackObj). create_UVCPreview always news a UVCPreview and ignores the previous pointer, so the old instance (and its callback global ref) is abandoned.
DeleteGlobalRef currently exists only on the replace / missing-onFrame paths, not on destructor or same-callback re-register.
Suggested fix
1. If IsSameObject is true, DeleteGlobalRef the newly created handle (keep the existing mFrameCallbackObj).
2. In ~UVCPreview(), attach if needed and DeleteGlobalRef(mFrameCallbackObj).
3. In create_UVCPreview, destroy/stop the previous instance before allocating a new one.
Summary
PreviewPrepareStream/PreviewPrepareTestcreate a JNI global reference forjIFrameCallbackand pass it tosetFrameCallback. That reference is not reliably released when the same callback is registered again, or when theUVCPreviewinstance is replaced/destroyed. Repeated prepare can grow the JNI global reference table.Location
app/src/main/cpp/libUvc_Support/uvc_support.cppJava_humer_UvcCamera_StartIsoStreamActivityUvc_PreviewPrepareStreamJava_humer_UvcCamera_SetUpTheUsbDeviceUvc_PreviewPrepareTestapp/src/main/cpp/libUvc_Support/UVC_Camera_Saki/UVCPreview.cppUVCPreview::setFrameCallbackUVCPreview::~UVCPreviewcreate_UVCPreviewDetails
Both JNI entry points do: