1

I'm developing a mobile application for Android using Qt. I've read this question about connecting to QApplication::aboutToQuit and/or QApplication::lastWindowClosed in order to do last-minute cleanup. However, I have found these methods insufficient when the user swipes to clear an application from the multitasking menu in Android. In this case it seems neither signal is broadcast and my application data is left in an inappropriate state. Is there any way to ensure that cleanup is done regardless of how the app is closed?

I've set up the following test code to verify they're not being broadcast:

#include <QGuiApplication>
#include <QDebug>

class Application : public QGuiApplication
{
  Q_OBJECT

  public:
    Application(int &argc, char **argv, int flags = ApplicationFlags)
        : QGuiApplication(argc, argv, flags) {

      connect(this, &QGuiApplication::aboutToQuit, 
              &Application::notifyQuitting);

      connect(this, &QGuiApplication::lastWindowClosed, 
              &Application::notifyLastWindowClosed);
    }

    static void notifyQuitting() {
      qDebug() << "quitting!";
    }

    static void notifyLastWindowClosed() {
      qDebug() << "LastWindowClosed!";
    }
};

Update:

I've implemented a custom Activity in Java and found that it seems that all three of onPause, onStop, and onDestroy are called whenever the application is killed in this manner. Of course, onStop and onDestroy may never be called if the device is low on memory, so the only surefire way to do it is in onPause.

It also seems that Qt has the signal QGuiApplication::applicationStateChanged, though I haven't looked into this much.

Jon McClung
  • 1,619
  • 20
  • 28
  • This is a problem with (almost) all mobile OSes. They do not implement proper shutdown (to improve responsiveness). The best option is to perform all necessary cleanup (i.e. make the app ready for being killed) when your application looses focus, i.e. when the user selects another mobile app/home screen. Note that saving your data on a mobile app is mostly done real-time. This is somewhat different from a typical desktop application. – m7913d Jul 06 '17 at 14:22
  • @m7913d Not the answer I was looking for, but thanks for letting me know. – Jon McClung Jul 06 '17 at 14:25

1 Answers1

0

If the cleanup you're trying to do is very important, consider using a Service that performs the cleanup when the task is removed. This will nearly guarantee the cleanup will be done. As long as the system is not very low on memory and the user doesn't stop the service on their own.

public class CleanupService extends Service {

    private static boolean cleanupDone = false;

    public CleanupService() {
        super();
        instance = this;
    }

    private void cleanupBeforeQuit() {
        // do cleanup here
        cleanupDone = true;
        stopSelf();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (cleanupDone) {
            stopSelf();
            return START_NOT_STICKY;
        }
        return START_STICKY;
    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        cleanupBeforeQuit();
        super.onTaskRemoved(rootIntent);
    }
}
Jon McClung
  • 1,619
  • 20
  • 28