# Flutter android project main thread issue

**URL:** <https://forum.juce.com/t/flutter-android-project-main-thread-issue/64343>\
**Category:** Android\
**Created:** [November 21, 2024, 8:35pm UTC](https://forum.juce.com/t/flutter-android-project-main-thread-issue/64343 "2024-11-21T20:35:25Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![chanonly123](https://avatars.discourse-cdn.com/v4/letter/c/5e9695/32.png) [@chanonly123](https://forum.juce.com/u/chanonly123)\
**Post date:** [November 21, 2024, 8:35pm UTC](https://forum.juce.com/t/flutter-android-project-main-thread-issue/64343/1 "2024-11-21T20:35:25Z")

</div>

I am working on a flutter UI project with juce player (non UI). The flutter iOS is working properly but crashing Android When executing

```auto
    auto ins = juce::MessageManager::getInstance();
    ins->callAsync([=] {
        deviceManager = new juce::AudioDeviceManager();
        deviceManager->addAudioCallback(player);
        deviceManager->initialiseWithDefaultDevices(0, 2);
    });

```

Error logs

```auto
F/ple.flutter_app( 4233): java_vm_ext.cc:598] JNI DETECTED ERROR IN APPLICATION: JNI CallBooleanMethodV called with pending exception java.lang.RuntimeException: Can't create handler inside thread Thread[1.ui,6,main] that has not called Looper.prepare()
F/ple.flutter_app( 4233): java_vm_ext.cc:598] at void android.os.Handler.<init>(android.os.Handler$Callback, boolean) (Handler.java:228)
F/ple.flutter_app( 4233): java_vm_ext.cc:598] at void android.os.Handler.<init>() (Handler.java:130)
F/ple.flutter_app( 4233): java_vm_ext.cc:598]
F/ple.flutter_app( 4233): java_vm_ext.cc:598] in call to CallBooleanMethodV
F/ple.flutter_app( 4233): runtime.cc:708] Runtime aborting...
F/ple.flutter_app( 4233): runtime.cc:708] Dumping all threads without mutator lock held
F/ple.flutter_app( 4233): runtime.cc:708] All threads:
F/ple.flutter_app( 4233): runtime.cc:708] DALVIK THREADS (22):
F/ple.flutter_app( 4233): runtime.cc:708] "main" prio=10 tid=1 Native
F/ple.flutter_app( 4233): runtime.cc:708] | group="" sCount=1 ucsCount=0 flags=1 obj=0x732869b8 self=0xb4000076c520a380
F/ple.flutter_app( 4233): runtime.cc:708] | sysTid=4233 nice=-10 cgrp=top-app sched=0/0 handle=0x785fd42d20
F/ple.flutter_app( 4233): runtime.cc:708] | state=S schedstat=( 507985878 721643085 1001 ) utm=32 stm=18 core=2 HZ=100
F/ple.flutter_app( 4233): runtime.cc:708] | stack=0x7fc5fbb000-0x7fc5fbd000 stackSize=8188KB
F/ple.flutter_app( 4233): runtime.cc:708] | held mutexes=
F/ple.flutter_app( 4233): runtime.cc:708] native: #00 pc 000be988 /apex/com.android.runtime/lib64/bionic/libc.so (__epoll_pwait+8) (BuildId: 1b9fecf834d610f77e641f026ca7269b)
F/ple.flutter_app( 4233): runtime.cc:708] native: #01 pc 00014030 /system/lib64/libutils.so (android::Looper::pollOnce+208) (BuildId: bca9105c866a03c2ff96b7e1fedd6c08)
F/ple.flutter_app( 4233): runtime.cc:708] native: #02 pc 00183bb8 /system/lib64/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce+44) (BuildId: 7e2a886b7a4523debea27d91258da727)
F/ple.flutter_app( 4233): runtime.cc:708] native: #03 pc 0019d09c [anon_shmem:dalvik-jit-code-cache] (offset 2000000) (art_jni_trampoline+140)
F/ple.flutter_app( 4233): runtime.cc:708] native: #04 pc 0006bc8c [anon_shmem:dalvik-jit-code-cache] (offset 2000000) (android.os.MessageQueue.next+332)
F/ple.flutter_app( 4233): runtime.cc:708] native: #05 pc 0006b094 [anon_shmem:dalvik-jit-code-cache] (offset 2000000) (android.os.Looper.loopOnce+164)
F/ple.flutter_app( 4233): runtime.cc:708] native: #06 pc 0036de40 /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+640) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #07 pc 0036725c /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false>+2048) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #08 pc 0076e170 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp<false>+12208) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #09 pc 003869d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #10 pc 0020c7c0 /system/framework/framework.jar (android.os.Looper.loop)
F/ple.flutter_app( 4233): runtime.cc:708] native: #11 pc 00359650 /apex/com.android.art/lib64/libart.so (art::interpreter::Execute +428) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #12 pc 00367a78 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false>+4124) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #13 pc 0076e170 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp<false>+12208) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #14 pc 003869d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #15 pc 001d605c /system/framework/framework.jar (android.app.ActivityThread.main)
F/ple.flutter_app( 4233): runtime.cc:708] native: #16 pc 003589dc /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+1932) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #17 pc 00384498 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #18 pc 0036de40 /apex/com.android.art/lib64/libart.so (art_quick_invoke_static_stub+640) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #19 pc 003698f4 /apex/com.android.art/lib64/libart.so (_jobject* art::InvokeMethod<8>+732) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #20 pc 006c6738 /apex/com.android.art/lib64/libart.so (art::Method_invoke +32) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #21 pc 00384370 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+144) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #22 pc 0036db74 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #23 pc 003671e4 /apex/com.android.art/lib64/libart.so (bool art::interpreter::DoCall<false>+1928) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #24 pc 0076e170 /apex/com.android.art/lib64/libart.so (void art::interpreter::ExecuteSwitchImplCpp<false>+12208) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #25 pc 003869d8 /apex/com.android.art/lib64/libart.so (ExecuteSwitchImplAsm+8) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #26 pc 001d2704 /system/framework/framework.jar (com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run)
F/ple.flutter_app( 4233): runtime.cc:708] native: #27 pc 003589dc /apex/com.android.art/lib64/libart.so (artQuickToInterpreterBridge+1932) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] native: #28 pc 00384498 /apex/com.android.art/lib64/libart.so (art_quick_to_interpreter_bridge+88) (BuildId: 3f7d5a016e08d528f129bdd336d81168)
F/ple.flutter_app( 4233): runtime.cc:708] at android.os.MessageQueue.nativePollOnce(Native method)
F/ple.flutter_app( 4233): runtime.cc:708] at android.os.MessageQueue.next(MessageQueue.java:346)
F/ple.flutter_app( 4233): runtime.cc:708] at android.os.Looper.loopOnce(Looper.java:189)
F/ple.flutter_app( 4233): runtime.cc:708] at android.os.Looper.loop(Looper.java:317)
F/ple.flutter_app( 4233): runtime.cc:708] at android.app.ActivityThread.main(ActivityThread.java:8705)
F/ple.flutter_app( 4233): runtime.cc:708] at java.lang.reflect.Method.invoke(Native method)
F/ple.flutter_app( 4233): runtime.cc:708] at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
F/ple.flutter_app( 4233): runtime.cc:708] at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)
F/ple.flutter_app( 4233): runtime.cc:708]
F/ple.flutter_app( 4233): runtime.cc:708] "ReferenceQueueDaemon" prio=5 tid=6 Waiting
F/ple.flutter_app( 4233): runtime.cc:708] | group="" sCount=1 ucsCount=0 flags=1 obj=0x14000830 self=0xb4000076c5205010
F/ple.flutter_app( 4233): runtime.cc:708] | sysTid=4244 nice=4 cgrp=top-app sched=0/0 handle=0x7570700730
F/ple.flutter_app( 4233): runtime.cc:708] | state=S schedstat=( 3709044 1465124 3 ) utm=0 stm=0 core=1 HZ=100
F/ple.flutter_app( 4233): runtime.cc:708] | stack=0x75705fd000-0x75705ff000 stackSize=1037KB
F/ple.flutter_app( 4233): runtime.cc:708] | held mutexes=

```

Note:

1. Not using projucer to generate the android app project
2. Generated android (shared) and iOS (static) libs binary
3. Copy them to respected flutter project,
4. Without main thread related juce apis working.
5. Coppied `flutter_app/android/app/src/main/java/com/rmsl/juce/Java.java` and `flutter_app/android/app/src/main/java/com/rmsl/juce/Receiver.java` to flutter project

My project is open soruce, please take a look `https://github.com/chanonly123/juce_audio_player`

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [November 21, 2024, 10:38pm UTC](https://forum.juce.com/t/flutter-android-project-main-thread-issue/64343/2 "2024-11-21T22:38:46Z")

</div>

> [@chanonly123](#):
>
> `Can't create handler inside thread Thread[1.ui,6,main] that has not called Looper.prepare()`

I’ve not seen this error before, but it sounds like you may not have initialised the message manager thread correctly. Are you using ScopedJuceInitialiser\_GUI anywhere?

---

<div class="post-metadata">

**Author:** ![chanonly123](https://avatars.discourse-cdn.com/v4/letter/c/5e9695/32.png) [@chanonly123](https://forum.juce.com/u/chanonly123)\
**Post date:** [November 22, 2024, 8:50am UTC](https://forum.juce.com/t/flutter-android-project-main-thread-issue/64343/3 "2024-11-22T08:50:16Z")

</div>

Not using ScopedJuceInitialiser\_GUI anywhere.  
Since I am not using projucer generated android project, do I have to call some more juce setup methods?  
Already caling `Java.initialiseJUCE (this);` in AndroidApplication.

---

<div class="post-metadata">

**Author:** ![reuk](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/reuk/32/21494_2.png) [@reuk](https://forum.juce.com/u/reuk)\
**Post date:** [November 22, 2024, 9:40pm UTC](https://forum.juce.com/t/flutter-android-project-main-thread-issue/64343/4 "2024-11-22T21:40:30Z")

</div>

That’s my best guess. Maybe you could try adding a ScopedJuceInitialiser\_GUI instance that is created after loading your library, and destroyed just before unloading it.

---

<div class="post-metadata">

**Author:** ![adamwilson](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/adamwilson/32/1387_2.png) [@adamwilson](https://forum.juce.com/u/adamwilson)\
**Post date:** [November 24, 2024, 11:09pm UTC](https://forum.juce.com/t/flutter-android-project-main-thread-issue/64343/5 "2024-11-24T23:09:52Z")

</div>

We had a very a rough time getting a similar setup working.

In our case, we did need the message thread to be started. Since the Dart VM and Java VM are completely separate, there was quite a bit of work that needed to be done to get things communicating properly. Many JUCE methods on Android rely on interacting with the Java side.

However, now that we’re past that pain we can set up functions in C++ and call them via Dart (via a C API) without touching JNI 🙂

---

<div class="post-metadata">

**Author:** ![chanonly123](https://avatars.discourse-cdn.com/v4/letter/c/5e9695/32.png) [@chanonly123](https://forum.juce.com/u/chanonly123)\
**Post date:** [November 25, 2024, 7:39am UTC](https://forum.juce.com/t/flutter-android-project-main-thread-issue/64343/6 "2024-11-25T07:39:28Z")

</div>

Thank you @reuk, `ScopedJuceInitialiser_GUI ` isnt working.  
Thank you @adamwilson kinda guessed the same dart\_vm/java\_vm issue. How much work/magic need exactly? can you suggest should I opt for flutter method channel?  
Im spending sleepless nights here 🥲.

---

<div class="post-metadata">

**Author:** ![chanonly123](https://avatars.discourse-cdn.com/v4/letter/c/5e9695/32.png) [@chanonly123](https://forum.juce.com/u/chanonly123)\
**Post date:** [December 16, 2024, 3:50pm UTC](https://forum.juce.com/t/flutter-android-project-main-thread-issue/64343/7 "2024-12-16T15:50:01Z")

</div>

I have fixed the issue.  
I had to call `juce::MessageManager::getInstance();` from java using a jni method in Android.  
also calling the same in the AppDelegate in iOS.  
Now we can use the MessageManager from Flutter.
