Android crash with HighResolutionTimer and MessageManagerLock

I am integrating JUCE code inside an existing Android application. So far so good, I can add an AudioProcessorEditor using addToDesktop() and all shows fine and I can interact with controls.

Some GUI items however, need to be updated at regular intervals (like VU meters). However, since the JAVA part runs the message loop, the Message system of JUCE is not running its own message loop for the UI. Timer callbacks are therefore not called. One proposed ‘fix’ was to use a HighResolutionTimer, but since that runs in its own thread, some sort of ‘runOnUiThread()’ call like on Android would be needed. The use of MessageManagerLock causes a crash:

com.test.test A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x20 in tid 22738 (test), pid 22667 (test) (juce::CriticalSection::enter() const+20) (juce::GenericScopedLock<juce::CriticalSection>::GenericScopedLock(juce::CriticalSection const&)+36) (juce::ReferenceCountedArray<juce::MessageManager::MessageBase, juce::CriticalSection>::add(juce::MessageManager::MessageBase*)+64) (juce::ReferenceCountedArray<juce::MessageManager::MessageBase, juce::CriticalSection>::add(juce::ReferenceCountedObjectPtr<juce::MessageManager::MessageBase> const&)+56) (juce::AndroidMessageQueue::post(juce::ReferenceCountedObjectPtr<juce::MessageManager::MessageBase>&&)+84) (juce::MessageManager::postMessageToSystemQueue(juce::MessageManager::MessageBase*)+64) (juce::MessageManager::MessageBase::post()+88) (juce::MessageManager::Lock::tryAcquire(bool) const+376) (juce::MessageManager::Lock::tryEnter() const+28) (juce::MessageManagerLock::attemptLock(juce::Thread*, juce::ThreadPoolJob*)+312) (juce::MessageManagerLock::MessageManagerLock(juce::Thread*)+144) (MyTimer::hiResTimerCallback()+100) (juce::HighResolutionTimer::Pimpl::timerThread()+308) (juce::HighResolutionTimer::Pimpl::timerThread(void*)+28) 

Any hints?

I think MessageManager::callAsync() does what exaclty what you need.

Asynchronously invokes a function or C++11 lambda on the message thread.

I’m afraid this would suffer the same problem, since the MessageManager and the Timer problem are related.

Since it is not a JCUEApplication, your existing JAVA application would be in charge to do those calls synchronously.

However, I would expect all kinds of problems, when using JUCE components without a JUCEApplication, so I think you would need to reverse the setup, have a JUCEApplication and somehow wrap the existing JAVA code.

The app is probably one of the biggest apps in existence on Android and has been in development for over 5 years. We can’t and won’t change it to a JUCEApplication of course.

In that case I would make a clear cut between frontend and backend. For the frontend I think it is difficult to mix JUCE components and java drawing, since JUCE components rely on a MessageManager being run.

An alternative I could imagine is a custom MessageManager, that is actually triggered from the java message thread (i.e. periodically calls MessageManager::runDispatchLoopUntil (msecs). That would also make your Timer work.

I looked once into that complex in the sources, but haven’t implemented something like that myself, maybe somebody else has other ideas, how to mix…

Good luck

Well, mixing JUCE and Java UI is working fine. They are just different views and both Java and JUCE/OpenGL views get touch events, so that’s not an issue. I’ll just make a work-around.

Cool, good to hear.

If I call MessageManager::getInstance() once, the Android message handler is instantiated and everything just works! TriggerAsyncUpdate() in Timer didn’t work because the MessageManager apparently never got instantiated.

Great news! I missed that option, since I wrongly assumed, the native JAVA application and the JUCE message manager would contradict each other.

As side reference have also a look then into
ScopedJuceInitialiser_GUI. That would make sure a MessageManager is created and will get rid of it on shutdown avoiding any leaks.
Ignore the name, it won’t bring up its own GUI, but rather initialise all bridges to the windowing system.

Cool, I will check it out! In the JAVA part, you can also have multiple Handler’s which will call back on the UI, so I guess this is similar.