@@ -326,6 +326,74 @@ JNIEXPORT jboolean JNICALL Java_com_github_stephengold_joltjni_Jolt_implementsDe
326326#endif
327327}
328328
329+ JavaVM *gpVM; // the virtual machine used by both AndroidTrace() and JavaTrace()
330+
331+ #ifdef ANDROID
332+ jclass gLogClass ;
333+ jint gPriority ;
334+ jmethodID gPrintlnMethodId ;
335+ jstring gTag ;
336+ static void AndroidTrace (const char *inFormat, ...) {
337+ // Format the message:
338+ va_list list;
339+ va_start (list, inFormat);
340+ char buffer[1024 ];
341+ vsnprintf (buffer, sizeof (buffer), inFormat, list);
342+ va_end (list);
343+ //
344+ bool attachedHere = false ;
345+ JNIEnv *pAttachEnv;
346+ jint retCode = gpVM->GetEnv ((void **)&pAttachEnv, JNI_VERSION_1_6);
347+ if (JNI_EDETACHED == retCode) { // Attach env to the JVM:
348+ JavaVMAttachArgs jvmArgs;
349+ jvmArgs.version = JNI_VERSION_1_6;
350+ retCode = gpVM->AttachCurrentThread (reinterpret_cast <JNIEnv **>(&pAttachEnv), &jvmArgs);
351+ }
352+ JPH_ASSERT (JNI_OK == retCode);
353+ // Create a Java string for the message:
354+ jstring javaString = pAttachEnv->NewStringUTF (buffer);
355+ JPH_ASSERT (NULL != javaString);
356+ EXCEPTION_CHECK (pAttachEnv)
357+ // Send the message to the log with the configured priority and tag:
358+ pAttachEnv->CallStaticIntMethod (
359+ gLogClass , gPrintlnMethodId , gPriority , gTag , javaString);
360+ // Ignore the return value; don't check for exceptions.
361+ //
362+ if (attachedHere) { // Detach env from the JVM:
363+ gpVM->DetachCurrentThread ();
364+ }
365+ }
366+ #endif
367+
368+ /*
369+ * Class: com_github_stephengold_joltjni_Jolt
370+ * Method: installAndroidTraceCallback
371+ * Signature: (ILjava/lang/String;)V
372+ */
373+ JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_Jolt_installAndroidTraceCallback
374+ (JNIEnv *pEnv, jclass, jint priority, jstring tag) {
375+ #ifdef ANDROID
376+ jint fail = pEnv->GetJavaVM (&gpVM);
377+ JPH_ASSERT (0 == fail);
378+ gLogClass = pEnv->FindClass (" android/util/Log" );
379+ JPH_ASSERT (NULL != gLogClass );
380+ EXCEPTION_CHECK (pEnv)
381+ gLogClass = (jclass) pEnv->NewGlobalRef (gLogClass );
382+ JPH_ASSERT (NULL != gLogClass );
383+ gPrintlnMethodId = pEnv->GetStaticMethodID (
384+ gLogClass , " println" , " (ILjava/lang/String;Ljava/lang/String;)I" );
385+ JPH_ASSERT (NULL != gPrintlnMethodId );
386+ EXCEPTION_CHECK (pEnv)
387+ //
388+ gPriority = priority;
389+ gTag = (NULL == tag) ? NULL : (jstring) pEnv->NewGlobalRef (tag);
390+ Trace = AndroidTrace;
391+ #elif defined(JPH_DEBUG)
392+ std::cout << " Jolt.installAndroidTraceCallback() has no effect on desktop platforms."
393+ << std::endl;
394+ #endif
395+ }
396+
329397/*
330398 * Class: com_github_stephengold_joltjni_Jolt
331399 * Method: installAssertCallback
@@ -469,7 +537,6 @@ JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_Jolt_installIgnoreAss
469537#endif
470538}
471539
472- JavaVM *gpVM;
473540jmethodID gFlushMethodId , gPrintMethodId ;
474541jobject gTraceStream ;
475542static void JavaTrace (const char *inFormat, ...) {
0 commit comments