You should certainly use the QueueConnection. I assume you are familiar with https://www.kdab.com/qt-android-episode-7/ ? I always decouple them by sending a signal and connecting a slot (which implies a queuedConnection). This is most likely equivalent to QMetaObject::invokeMethod() with „QueuedConnection“ but I'm not that familiar with QMetaObject::invokeMethod.
Another explanation for what you observe is that the second call to updateList originates from within the first call somehow. This can be validated by dumping a call-stack when entering updateList (or set a breakpoint but that's probably not that easy in a Service) Hope this helps, Marc On Mon, 13 Jul 2020 at 16:53, Fabrice Mousset | GEOCEPT GmbH < fabrice.mous...@geocept.com> wrote: > Yes, JniHandler::stateChanged is called from Java. > I tried many ways: > * QMetaObject::invokeMethod() with „AutoConnection“ > * QMetaObject::invokeMethod() with „QueuedConnection“ > * QTimer::singleShot() > > What will be different by using „emit pInstance ->signalName()“ ? > > Regards > > Fabrice > > Von: Marc Van Daele <marc.van.dael...@gmail.com> > Gesendet: Montag, 13. Juli 2020 16:45 > An: Fabrice Mousset | GEOCEPT GmbH <fabrice.mous...@geocept.com> > Cc: Qt Interest <interest@qt-project.org> > Betreff: Re: [Interest] Trouble with Android JNI and QEventLoop > > The JniHandler::stateChanged is called from Android/Java (or Kotlin) I > guess? > Can you try to emit a signal in JniHandler::stateChanged and call the > updateList in the connected slot? > > Marc > > > > On Mon, 13 Jul 2020 at 16:15, Fabrice Mousset | GEOCEPT GmbH <mailto: > fabrice.mous...@geocept.com> wrote: > Thanks for your reply! > > The thread ID is the same, all messages are from the same process > (Activity and Service are on different processes). > I forgot to say that I have already tried QMutex to lock the access, but > that is not useful here because if I set it up as "NonRecursive", it will > dead lock! > > Regards > > Fabrice > > Von: Marc Van Daele <mailto:marc.van.dael...@gmail.com> > Gesendet: Montag, 13. Juli 2020 11:36 > An: Fabrice Mousset | GEOCEPT GmbH <mailto:fabrice.mous...@geocept.com> > Cc: Qt Interest <mailto:interest@qt-project.org> > Betreff: Re: [Interest] Trouble with Android JNI and QEventLoop > > Can you also print the thread-pointer/id next to the name? > Maybe (just guessing) one QtMainLoopThread is from the main app and the > other one is from the service? > You could add a QMutexLocker (https://doc.qt.io/qt-5/qmutexlocker.html) > to ensure that the calls are executed sequentially. > > Kind Regards, > > Marc > > On Mon, 13 Jul 2020 at 09:25, Fabrice Mousset | GEOCEPT GmbH <mailto: > mailto:fabrice.mous...@geocept.com> wrote: > Hi all, > > First, I tried to send this mail to Android mailing list, but got an error > message as reply, so I try here. Sorry if I am wrong > > I have a random issue with one of my Android service I've build with Qt > 5.12.9. > I have centralized JNI interface in one C++ class, which is a singleton. > My service is single threaded, so there should not be a threading issue... > I guess! > > So here my issue: I have a function which will populate a list. This > function could be called at service begin or while receiving a specific > Broadcast message. > Sometimes, it happens that this function is called twice before first call > is finished. > > I have at some traces to follow what's happening, something like: > void MyService::updateList(int calledFrom) { > qDebug() << "Update List start #"<< calledFrom << "@" << > QThread::currentThread()->objectName(); > ... > qDebug() << "Update List end #"<< calledFrom << "@" << > QThread::currentThread()->objectName();} > } > > And, on LogCat I can see: > Update List start # 0 @ "QtMainLoopThread" > Update List start # 1 @ "QtMainLoopThread" > Update List end # 1 @ "QtMainLoopThread" > Update List end # 0 @ "QtMainLoopThread" > > > Here is the way I handle JNI calls: > void JniHandler:: stateChanged(JNIEnv *, jobject, jint newState) { > auto* pInstance = JniHandler::instance(); > if(pInstance) > { > QMetaObject::invokeMethod(pInstance, [pInstance , newState] { > ... > }); > } > } > > I tried to change QMetaObject::invokeMethod call to add ' > Qt::QueuedConnection', but didn't change anything. > I also change to use QTimer::singleShot(): > if(pInstance) > { > QEventLoop myLoop; > Q_UNUSED(myLoop) > QTimer::singleShot(0, pInstance, [pInstance , newState] { > ... > }); > } > > But still have the same issue. > > How is this possible? > What I am doing wrong? > > Best regards > > Fabrice Mousset > > _______________________________________________ > Interest mailing list > mailto:mailto:Interest@qt-project.org > https://lists.qt-project.org/listinfo/interest >
_______________________________________________ Interest mailing list Interest@qt-project.org https://lists.qt-project.org/listinfo/interest