Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Timer stops/pauses if Activity is suspended in Android



  • I was wondering if I encoutered a bug in Qt / QML or this is by purpose:

    In my application I am using a Timer from QML, which assures connection with the server by sending keepalives every few seconds. But if another Activity is opened over my Main Activity (for example an AdMob Interstitial), the triggered-signals seem to don't get called anymore?

    After a little recherche I discovered that the Timer is synchronized with the animation timer, which makes sense i quess?

    But if I build the same application for iOs oder Desktop that doesn't seem to be the case?

    Is there a way to achieve a unified behavior over all platforms?
    (I tried setting the meta flag "<meta-data android:name="android.app.background_running" android:value="false"/>" to true, which seem to work, but is not recommended as I understand and comes with a lot of work on other ends)

    Another way to solve this, would be to use a QTimer in the c++ side of my code,
    but I just wanted to ask if the stated behavior is intended or if I am overlooking something here?

    best regards
    SyntaX



  • @SyntaX said in Timer stops/pauses if Activity is suspended in Android:

    But if another Activity is opened over my Main Activity (for example an AdMob Interstitial), the triggered-signals seem to don't get called anymore?

    Hello, as far as I know, on Android when an Activity goes to background, the Activity is stopped. So all Timers (even in C++) as stopped. Take a look at Android documentation
    a071510b-8f89-4829-9f2c-8943aa21e702-image.png

    So this is not a Qt/QML bug, it is the way Android is working!



  • Hey @KroMignon and thanks for your reply :D

    I am aware of the Activity lifecycle, though, if I insert a Timer / runnable inside my main Activity, those triggers still get called, if another Activity is shown on Top

    code

    // test timer in Activity.onCreate
    final long startTime = 0;
    final Handler timerHandler = new Handler();
    Runnable timerRunnable = new Runnable() {
    
        @Override
        public void run() {
            long millis = System.currentTimeMillis() - startTime;
            int seconds = (int) (millis / 1000);
            int minutes = seconds / 60;
            seconds = seconds % 60;
    
            log(String.format("%d:%02d", minutes, seconds)); // this still gets called
    
            timerHandler.postDelayed(this, 500);
        }
    };
    timerHandler.postDelayed(timerRunnable, 0);
    

    Through my research I found a similar question on stackOverflow and it seems, this was a fix in Qt 5.4.

    I was just wondering, why the behaviour for Timer in QML seems to be different on iOS/desktop and Android and if it is intentional.



  • @SyntaX said in Timer stops/pauses if Activity is suspended in Android:

    I was just wondering, why the behaviour for Timer in QML seems to be different on iOS/desktop and Android and if it is intentional.

    You are misunderstanding something I guess. When Android put the activity into "onStop()", the activity will never gain CPU time, so no timer can work.
    On Windows/Linux/MacOS, the application will never be "frozen", so Timer will always got CPU time to execute.
    The only way to solve this with Android, is to use a Service and not an Activity.



  • @KroMignon said in Timer stops/pauses if Activity is suspended in Android:

    When Android put the activity into "onStop()",

    Ah sorry, what I meant was "onPause()" (that's the specific case I am dealing with) but I think this doesn't matter?
    Because the Runnable doesn't stop if I show an AdMob Interstitial on top of my main Activity, just the QML Timer stops sending events?

    best regards and thanks for your support,
    SyntaX



  • @SyntaX said in Timer stops/pauses if Activity is suspended in Android:

    Ah sorry, what I meant was "onPause()" (that's the specific case I am dealing with) but I think this doesn't matter?
    Because the Runnable doesn't stop if I show an AdMob Interstitial on top of my main Activity, just the QML Timer stops sending events?

    Hmm, I don't know what happen with QML Engine when Activity is going into "Pause" state, and I can not find anything in documentation.
    It is an interesting question.
    What about QTimer? Do they continue to work?

    Perhaps this is something you should submit to developer mailing list: https://lists.qt-project.org/listinfo/android-development



  • @KroMignon said in Timer stops/pauses if Activity is suspended in Android:

    What about QTimer? Do they continue to work?

    I added a temporary QTimer in MyClass derived from Object:

    {
        ...
        // init in ctor:
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(debugOutput()));
        timer->start();
    }
    
    // with the following callback:
    void MyClass::debugOutput() {
        qDebug().noquote().nospace() << QTime::currentTime().toString() << " keepalive...";
    }
    

    After Opening an AdMob Interstitial, the Java Main Activity gets suspended (onPause gets called) and debugOutput stops printing.
    Curiously, if I close my App (push the Home button and onStop gets called) the keepalive output continues?

    Sadly I also wasn't able to find a good documentation covering the intended behaviour of Timer / Activity-lifecycle related specifications.

    I will submit to the mailing list and report back, if I gather new intel.

    Thanks again for your help,
    best regards
    SyntaX



  • @KroMignon Sorry for bothering you again, but I have to admit, that I never before submitted to a dev mailing list xD

    Do I just send an Email to android-development@qt-project.org and everyone who is subscribed gets the message? Seems a bit of a overkill like @everyone to me?



  • @SyntaX said in Timer stops/pauses if Activity is suspended in Android:

    Do I just send an Email to android-development@qt-project.org and everyone who is subscribed gets the message? Seems a bit of a overkill like @everyone to me?

    No problem, you first have to register to the mailing list, and then you can send emails to it. This is the Qt-Android developers mailing list. So your mail will be received by each member.
    That's the way mailing lists works ;-)

    You can also try to contact BogDan Vatra from KDAB, which is the main developer of Qt/Android