[Interest] Trouble with Android JNI and QEventLoop

Marc Van Daele marc.van.daele90 at gmail.com
Mon Jul 13 17:10:14 CEST 2020


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.mousset at 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.daele90 at gmail.com>
> Gesendet: Montag, 13. Juli 2020 16:45
> An: Fabrice Mousset | GEOCEPT GmbH <fabrice.mousset at geocept.com>
> Cc: Qt Interest <interest at 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.mousset at 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.daele90 at gmail.com>
> Gesendet: Montag, 13. Juli 2020 11:36
> An: Fabrice Mousset | GEOCEPT GmbH <mailto:fabrice.mousset at geocept.com>
> Cc: Qt Interest <mailto:interest at 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.mousset at 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 at qt-project.org
> https://lists.qt-project.org/listinfo/interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20200713/14c18f5f/attachment-0001.html>


More information about the Interest mailing list