Skip to content

Instantly share code, notes, and snippets.

@atsushieno
Created March 11, 2022 11:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atsushieno/8e176beca9d6fd4ea91a6953838195b6 to your computer and use it in GitHub Desktop.
Save atsushieno/8e176beca9d6fd4ea91a6953838195b6 to your computer and use it in GitHub Desktop.
diff --git a/modules/juce_core/native/juce_android_JNIHelpers.h b/modules/juce_core/native/juce_android_JNIHelpers.h
index 4131d326f..2924baf0c 100644
--- a/modules/juce_core/native/juce_android_JNIHelpers.h
+++ b/modules/juce_core/native/juce_android_JNIHelpers.h
@@ -769,6 +769,14 @@ DECLARE_JNI_CLASS (AndroidBuildVersion, "android/os/Build$VERSION")
DECLARE_JNI_CLASS (AndroidSurfaceHolder, "android/view/SurfaceHolder")
#undef JNI_CLASS_MEMBERS
+#define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD, CALLBACK) \
+ METHOD (constructor1, "<init>", "(Ljava/lang/Runnable;)V") \
+ METHOD (constructor2, "<init>", "(Ljava/lang/Runnable;Ljava/lang/String;)V") \
+ METHOD (start, "start", "()V") \
+
+DECLARE_JNI_CLASS (JavaLangThread, "java/lang/Thread")
+#undef JNI_CLASS_MEMBERS
+
//==============================================================================
namespace
{
diff --git a/modules/juce_core/native/juce_posix_SharedCode.h b/modules/juce_core/native/juce_posix_SharedCode.h
index dbf06043a..c04ba9518 100644
--- a/modules/juce_core/native/juce_posix_SharedCode.h
+++ b/modules/juce_core/native/juce_posix_SharedCode.h
@@ -882,6 +882,32 @@ static void* threadEntryProc (void* userData)
extern pthread_t juce_createRealtimeAudioThread (void* (*entry) (void*), void* userPtr);
#endif
+#if ANDROID
+class ThreadTargetRunnable : public AndroidInterfaceImplementer
+{
+ Thread *juce_thread;
+public:
+ ThreadTargetRunnable(Thread *juceThread) : juce_thread(juceThread) {}
+
+ jobject invoke (jobject proxy, jobject method, jobjectArray args) override
+ {
+ auto* env = getEnv();
+
+ auto methodName = juceString ((jstring) env->CallObjectMethod (method, JavaMethod.getName));
+
+ if (methodName == "run")
+ {
+ juce_thread->threadHandle.set((void*) pthread_self());
+ juce_thread->threadId = (Thread::ThreadID) juce_thread->threadHandle.get();
+ threadEntryProc(juce_thread);
+ return nullptr;
+ }
+
+ return AndroidInterfaceImplementer::invoke (proxy, method, args);
+ }
+};
+#endif
+
void Thread::launchThread()
{
#if JUCE_ANDROID
@@ -903,6 +929,18 @@ void Thread::launchThread()
pthread_attr_t attr;
pthread_attr_t* attrPtr = nullptr;
+#if JUCE_ANDROID
+ auto env = getEnv();
+ auto runnableNative = new ThreadTargetRunnable(this);
+ auto runnable = CreateJavaInterface(runnableNative, "java/lang/Runnable");
+ GlobalRef threadRunnableGRef { runnable };
+ auto name = env->NewStringUTF("ThreadTargetRunnable");
+ auto threadObj = env->NewObject(JavaLangThread, JavaLangThread.constructor1, threadRunnableGRef.get(), name);
+ GlobalRef threadGRef { LocalRef<jobject>(threadObj) };
+ javaThreadPeer = threadGRef;
+ env->CallVoidMethod(threadGRef.get(), JavaLangThread.start);
+#else
+
if (pthread_attr_init (&attr) == 0)
{
attrPtr = &attr;
@@ -919,6 +957,7 @@ void Thread::launchThread()
if (attrPtr != nullptr)
pthread_attr_destroy (attrPtr);
+#endif
}
void Thread::closeThreadHandle()
diff --git a/modules/juce_core/threads/juce_Thread.h b/modules/juce_core/threads/juce_Thread.h
index 5db90efcb..ad70793e0 100644
--- a/modules/juce_core/threads/juce_Thread.h
+++ b/modules/juce_core/threads/juce_Thread.h
@@ -381,6 +381,7 @@ public:
#endif
private:
+ friend class ThreadTargetRunnable; // needs to access threadHandle
//==============================================================================
const String threadName;
Atomic<void*> threadHandle { nullptr };
@@ -396,6 +397,7 @@ private:
#if JUCE_ANDROID
bool isAndroidRealtimeThread = false;
+ /*GlobalRef*/ void* javaThreadPeer { nullptr };
#endif
#ifndef DOXYGEN
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment