Getting kill signal on Android



  • I have an Android application and I need to know when the system wants to kill it. I need to react to the situation and save the current state (to a text file or database).

    On Windows and desktop Linux I have implemented an eventFilter where I catch QEvent::Close. But this doesn't seem to work on Android.

    I need to catch that my application is about to close in following situations:

    • The app is killed from task switcher
    • Android is shutting down
    • Android shuts down my application to free up memory

    Is it possible to catch these situations and execute some code before my app is killed?



  • I guess you can't get a kill signal, so you may need to settle for what you get, which may include
    Qt::ApplicationInactive
    Qt::ApplicationSuspended
    Qt::ApplicationHidden

    Some people with very small data in their app save it just in case every time the data changes. Of course it depends on the amount of data what strategy is the best.


  • Qt Champions 2016

    @vlada
    http://www.cplusplus.com/reference/csignal/signal/

    Try intercepting the termination signal (SIGTERM). However, depending on how Android handles things this might not be enough. If the OS kills your process there's nothing you can do about it.



  • Thank you for your replies. I was afraid that it is not possible to catch the KILL signal.

    My application is a music player. I wrote it mainly for my car radio with Android. So my main concern is to store the player state when Android shuts down (which happens when I remove keys from my car).

    So I guess the best practice would be to save the main settings (player settings, playlists, shuffle list, queue etc.) when a song changes. Then save the current song progress let's say every 10 seconds.

    Now what would you suggest to do. Should I store the progress to a SQLite database (where I store all the settings) or would it be more effective to store it to a plain text file with just a single number (elapsed seconds)? What would be more effective?



  • Disclaimer: I know a lot about how Qt's Android support works, but since there's been no definitive answers yet, I'll take stab in the dark... ;)

    Looking at some Android docs, it looks like you'd want to be handling at least the Activity::onPause event.

    Looking at the implementation of QtActivityDelegate::onPause (which appears to be the delegate that handles Android application events for Qt):

    public void onPause()
    {
        QtNative.setApplicationState(ApplicationInactive);
    }
    

    So perhaps connecting the QGuiApplication::applicationStateChanged signal to your own slot, and checking for the Qt::ApplicationInactive state (or perhaps any state other than Qt::ApplicationActive) will get you want you want?

    If you haven't already, its probably worth browsing the source for QtActivity and QtActivityDelegate to see what else they do that might be useful for you.

    Let us know how you go.

    Cheers.



  • @Paul-Colby Yes, I've already got the advice to watch for this signal from BogDan Vatra in a discussion under his article.

    I will try to watch what happens during the program lifecycle and if I can react to this signal. The problem is that my application must be working even in background (it is a music player). So it won't be simple.

    I'll check it and will let you know the result.



  • I did some tests on Android and I found that immediately as my application is sent to background, the state changes to Inactive and then very quickly to Suspended. But even in this state the music player continues to work.

    So there no use of these signals for me. In fact I need them but only to disable UI changes if application is not active.

    So the only solution remains to save the app state every few seconds. because it might get killed anytime without any previous warning.


  • Qt Champions 2016

    @vlada
    Again, have you tried intercepting the SIGTERM signal sent to the runtime?
    I don't know whether you program in Java for Android, but assuming you do this should be of help.



  • @kshegunov No, I haven't tried that yet. I was looking at the more simple (possible) solutions first.

    Unfortunately my application doesn't have any Java part (written by me) yet. I know that I will have to learn it and I have already studied the articles from BogDan Vatra on how to use Qt Android Extras and JNI. But I'm not familiar with that yet.


  • Qt Champions 2016

    @vlada

    No, I haven't tried that yet. I was looking at the more simple (possible) solutions first.

    Then you should attempt it and see if it works for you.

    Unfortunately my application doesn't have any Java part (written by me) yet.

    If you don't work with Java I then logically assume you use C++. The signal handling is part of the standard C runtime, so try that (for a link look at my first post in this thread).



  • @kshegunov Thanks a lot. At first I tried the example in your link which works fine. Then I tried to replace the signal SIGINT with SIGTERM. But the associated function gets never executed.

    Have I done anything wrong or is the application simply unable to catch the signal? I have tried it on Windows and switched my app off using all possible ways (taskbar, regular close, task manager). But nothing ever happened.


  • Qt Champions 2016

    @vlada said:

    Thanks a lot. At first I tried the example in your link which works fine. Then I tried to replace the signal SIGINT with SIGTERM. But the associated function gets never executed.

    Have I done anything wrong or is the application simply unable to catch the signal? I have tried it on Windows and switched my app off using all possible ways (taskbar, regular close, task manager). But nothing ever happened.

    It really depends how the Android (or the OS you were experimenting with) is trying to stop your program. If it tries to close it normally, you should try catching the QCoreApplication::aboutToQuit signal (this is a Qt signal). If it tries to stop your application forcefully, it should send the application process the SIGTERM (this is a process signal). And if it kills it (the most forceful of all), you can't react to it, because the runtime simply stops the process without any warning or waiting.

    PS. Sorry for the delay, I was pretty busy these two days.



  • @kshegunov I tried to catch all possible signals but I didn't get any of them. I think it is because of the way Qt applications are run on Android. Because on Android is run a Java application which runs my app as a library. Sorry for the probably incorrect wording.

    In this case it is the Java application which receives an onDestroy() signal. I'm wondering if this signal si somehow exposed to the C++ part. Another option would be to look into JNI and try to implement a custom handler for this signal which calls a C++ function in my app.

    But I'm trying to avoid the Java part as long as possible because I have no experience with that.


  • Qt Champions 2016

    @vlada said:

    I tried to catch all possible signals but I didn't get any of them. I think it is because of the way Qt applications are run on Android. Because on Android is run a Java application which runs my app as a library.

    Assuming this is true, then indeed, you'll need to write a bit of java and only if the Java runtime allows interception of the signals. I don't know if it's worth it, but it shouldn't be too hard.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.