QML: Manage application state on mobile systems

Develop app for mobile systems like Android or iOS require some additional steps compared to standard Desktop systems. One of the most important is to correctly manage the state change of your app. This is critical for avoid the app to consume CPU and battery when is not required.

As default behaviours in mobile system, indeed, when you "close" the current app the system doesn't close but, instead, put the app in a special suspend state without remove it from memory. This have as advantage that if you want to use the app again the app loading and starting is faster since all the required code and resource are already in memory just temporarily suspended. To be more precise, however, the system doesn't suspend the app but just "advise" the app that has been "closed" by the user and should stop every consuming activity. This is a very important clarification since this mean that if the app doesn't manage this system "advise" it will continue to run while not showed anymore in the screen. Thinking of a game, for example, the missing management of this suspend event will have the effect the game will continue to run on background consuming battery. As you can know this is a very BAD feature for the user that, probably, will uninstall your app very soon. Another important consequence to keep in mind is when your app will be switched to inactive mode is not sure it will be reactivated again. It will be kept in memory by the system until there will be memory space available, when the memory will finish the system will finally close your app. If your app have some data to save into the storage it could be a good idea to save it in this phase since you don't know what will happen in the future. QML already provided a property variable indicates the current state of the application. From official Qt documentation follow the possible values of application.state:

Qt.ApplicationActive - The application is the top-most and focused application, and the user is able to interact with the application.  

Qt.ApplicationInactive - The application is visible or partially visible, but not selected to be in front, the user cannot interact with the application. On desktop platforms, this typically means that the user activated another application. On mobile platforms, it is more common to enter this state when the OS is interrupting the user with for example incoming calls, SMS-messages or dialogs. This is usually a transient state during which the application is paused. The user may return focus to your application, but most of the time it will be the first indication that the application is going to be suspended. While in this state, consider pausing or stopping any activity that should not continue when the user cannot interact with your application, such as a video, a game, animations, or sensors. You should also avoid performing CPU-intensive tasks which might slow down the application in front. 

Qt.ApplicationSuspended - The application is suspended and not visible to the user. On mobile platforms, the application typically enters this state when the user returns to the home screen or switches to another application. While in this state, the application should ensure that the user perceives it as always alive and does not lose his progress, saving any persistent data. The application should cease all activities and be prepared for code execution to stop. While suspended, the application can be killed at any time without further warnings (for example when low memory forces the OS to purge suspended applications).  

Qt.ApplicationHidden - The application is hidden and runs in the background. This is the normal state for applications that need to do background processing, like playing music, while the user interacts with other applications. The application should free up all graphical resources when entering this state. A Qt Quick application should not usually handle this state at the QML level. Instead, you should unload the entire UI and reload the QML files whenever the application becomes active again.

As you can see there are four possible values but, basically, we can divide all the status in two main states, active and inactive (that cover all the three last states). Now, since this is a read only property the problem is to detect the property state change. This is a very easy task using QML connetions as follow:

Connections {
   target: Qt.application
   onStateChanged: {
      if(Qt.application.state === Qt.ApplicationActive)
         // Application go in active state
         // Application go in suspend state

Starting from this snippet you have to manage the suspend state in your app. Each activity CPU consuming need to be stopped or "suspended" and save your data if necessary. In case of game this mean the game must restart from the same point before go in suspension mode.


Post a Comment

Popular posts from this blog

Access GPIO from Linux user space

Launch an app from Android shell terminal

Android: adb push and read-only file system error