Home · All Classes · Main Classes · Deprecated |
An application that has been prestarted (or lazily shut down) can show its window almost without a delay when it is released from the prestarted state. MeeGo Touch supports prestarting and lazy shutdown of application services, that is, applications that are started by calling launch()
(or some other application-specific method) in their D-Bus interface.
Prestarted applications are started to a special prestarted state during boot by a daemon called Applifed. In that state, they are running in the background in their mainloop but do not show or do anything. If an application gets terminated, Applifed prestarts it again automatically.
When the user closes an application, lazy shutdown allows an application to enter the prestarted state instead of terminating it. This allows the next application to start up very quickly. To use this lazy shutdown feature an application shall be registered in Applifed configuration. Non-registered applications are closed by Applifed at the moment they returns from the running state to the prestarted state. Automatically prestarted applications can use lazy shutdown as well.
close()
method in the D-Bus interface.close()
method in the D-Bus interface.If an application supports prestarting, it must set the prestart mode with MApplication::setPrestartMode()
, regardless of the command line parameters, before using any other parts of the prestarting API. It is recommended to do this during or immediately after instantiating the MApplication
class.
It is important to notice that before entering the prestarted state application should do all the initializations that can be done before calling MWindow::show(). Some initializations eg. MApplicationPage::createContent are done only after MWindow::show() is called and prestarted state is released. In practice this means that window is visible for the user only after MApplicationPage::createContent() is finished.
Example:
// example.cpp // Minimal prestartable and lazy shutdownable application #include <MApplication> #include <MApplicationWindow> int main(int argc, char ** argv) { MApplication app(argc, argv); MApplication::setPrestartMode(M::LazyShutdown); MApplicationWindow window; window.show(); return app.exec(); }
Start the application to the prestarted state as follows.
$ ./example -prestart &
An application enters the prestarted state if it is started with the -prestart
commandline argument and it sets the prestart mode before showing any windows. If either one of these conditions does not hold, the application enters the running state.
The MApplicationWindow::show()
method can be called even if the application is in the prestarted state. The window will not become visible to the user until the application is launched.
MApplication::isPrestarted()
can be used to check if the application is currently in the prestarted state.
If the launch()
method in MApplication's D-Bus interface is called (for instance, when the user taps the application icon) and the application is in the prestarted state, the application is released from the prestarted state and allowed to continue to the running state. Make sure that the application registers exactly the same D-Bus service that is defined in the corresponding .service file. Contradictory services may lead to longer start-up times.
The default launch from the application grid can be simulated. For example:
$ dbus-send --dest=com.nokia.example --print-reply --type="method_call" /org/maemo/m com.nokia.MApplicationIf.launch
The application can also be released from the prestarted state in the code by calling MApplication::setPrestarted(false)
. This is equivalent to the D-Bus launch()
.
The application can react to the launch by connecting the MApplication::prestartReleased()
signal, or by overriding MApplication::releasePrestart() handler. The default handler shows the active window of a single-window application, if one exists. Note: default handler shows the window in the state where it was when it entered the prestart state. For example if application was minimized when entering the prestart state it will be shown as minimized when releasing it. If application developer wants to change this behaviour so that window isalways maximized it can be achieved for example by overriding MApplication::releasePrestart() handler and calling raise() for the active window.
For multi-window applications, the default handler does nothing. They must explicitly release the application from the prestarted state by calling MApplication::setPrestarted(false)
and show the window after that.
An application returns from running to prestarted state if its prestarted mode is set to M::LazyShutdown
or M::LazyShutdownMultiWindow
and its last window is closed.
The application can react to restoring the prestarted state by connecting to the MApplication::prestartRestored()
signal, or by overriding the MApplication::restorePrestart()
event handler. The default implementation of MApplication::restorePrestart()
hides all the open windows.
The application can also return to the prestarted state in the code by calling MApplication::setPrestarted(true)
. This effectively calls the MApplication::restorePrestart()
event handler if one of the lazy shutdown modes is set.
To enable lazy shutdown of the application or make the application prestartable during device boot, -prestart
must be added to the .service -file of the application:
[D-BUS Service] Name=com.nokia.example Exec=/usr/bin/example -prestart
Note: The above modification enables starting up and prestarting the application. It does not cause the application to start up or prestart at boot.
If Applifed is used for prestarting applications at boot, its configuration file is located in /etc/prestart
. This file contains the names of the prestartable D-Bus services and the prestarting priority among other things, such as CPU-load thresholds.
Boot time prestart configuration is typically part of the platform-specific configurations, and is not provided in application packages.
Applications in the prestarted state never interact with the user. They should not take care of any critical tasks, since configuration politics determine whether or not the applications is prestarted at all. Thus, the applications in the prestarted state are ideal candidates for suspending and killing when the system resources run low. Therefore, application developers must be aware that an application in the prestarted state may be killed with KILL signal at any time without any warning.
Multi-window applications can be prestarted by using LazyShutdownMultiWindow and TerminateOnCloseMultiWindow modes. As opposed to single-window applications, no window is shown by default when the launch() method is called from the D-Bus interface. The window is shown as follows:
1. The code releases the application from the prestarted state.
2. The code that handles the D-Bus call shows the window.
See the following example:
void MultiWindowApplication::activateWindow(int index) { // This is the real handler for D-Bus method activateWindow(int) // that shows a window (and page) of the given index. if (index >= 0 && index < NUM_WINDOWS) { // Force release from prestart if in prestarted state. // This is important, because it sets the internal state. if (isPrestarted()) { setPrestarted(false); } // Show the desired window m_window[index]->show(); m_window[index]->activateWindow(); m_window[index]->raise(); // Show the page and activate it m_mainPage[index]->appear(); m_mainPage[index]->activateWidgets(); } }
A multi-window application enters the prestarted state when all its windows are closed. Closed windows can be cleaned up, for instance, by the closeEvent handler of each window, or when restoring the prestarted state if all windows are closed.
The default behavior on window close varies depending on the prestart mode. On LazyShutdown and LazyShutdownMultiWindow windows are hidden by default. On TerminateOnClose and TerminateOnCloseMultWindow windows are really closed, just like when application has not been prestarted.
To change the default closing behaviour, override the closeEvent handler of the window and use MWindow::setCloseOnLazyShutdown
. See the following example:
#include <MApplication> #include <MApplicationWindow> #include <MApplicationPage> #include <MComboBox> #include <MDebug> #include <QStringList> class MyWindow : public MApplicationWindow { public: MyWindow(); protected: virtual void closeEvent(QCloseEvent *event); private: MApplicationPage *page; MComboBox *comboBox; }; MyWindow::MyWindow() { page = new MApplicationPage(); page->setTitle("closeEvent example app"); comboBox = new MComboBox(); comboBox->setTitle("What should closeEvent do?"); QStringList stringList; stringList << "Ignore closeEvent" << "Hide window (LazyShutdown)" << "Really close window"; comboBox->addItems(stringList); page->setCentralWidget(comboBox); page->appear(); } void MyWindow::closeEvent(QCloseEvent *event) { switch (comboBox->currentIndex()) { case 0: mDebug("MyWindow") << "Ignore closeEvent(). Window is not closed."; event->ignore(); break; case 1: mDebug("MyWindow") << "Lazy shutdown - hide the window"; setCloseOnLazyShutdown(false); event->accept(); break; case 2: default: mDebug("MyWindow") << "Lazy shutdown - really close the window"; setCloseOnLazyShutdown(true); event->accept(); break; } } int main(int argc, char **argv) { MApplication app(argc, argv); MApplication::setPrestartMode(M::LazyShutdown); MyWindow *window = new MyWindow(); window->show(); return app.exec(); }
The following example shows a skeleton of a single-window application. If -prestart
command line argument starts an application, it connects the signal for restoring the prestarted state to the slot that resets the page displayed in the window. Note: Showing and hiding the window does not require any actions from the application developer in single-window applications. For more information, see the default event handlers above.
// More complex LazyShutdown example using signals. // Using M::TerminateOnClose is just as simple, you'd just // set that mode without handling any prestart // restores or resets. class MainPage: public MApplicationPage { public slots: // Activate widgets here void activateWidgets(); // Deactivate widgets and reset state void resetState(); }; int main(int argc, char ** argv) { MApplication app(argc, argv); MApplication::setPrestartMode(M::LazyShutdown); MApplicationWindow window; window.show(); MainPage mainPage; mainPage.appear(); // Reset the state of the page shown on the window // when application returns from the running state // to the prestarted state app.connect(&app, SIGNAL(prestartRestored()), &mainPage, SLOT(resetState())); // Activate widgets when released from the prestarted state app.connect(&app, SIGNAL(prestartReleased()), &mainPage, SLOT(activateWidgets())); // Check if app is NOT in the prestarted state. This might // happen for example if the application is launched from the // application grid before Applifed has prestarted it or if it's // started without -prestart. if (!app.isPrestarted()) { // Activate widgets now mainPage.activateWidgets(); } return app.exec(); }
// Example of an application that supports LazyShutdown -prestarting using virtual handlers // (cannot be compiled due to missing implementation for the example page): class MyApplication : public MApplication { Q_OBJECT public: MyApplication(int & argc, char ** argv); ~MyApplication(); // Re-implementation virtual void releasePrestart(); // Re-implementation virtual void restorePrestart(); private: // Main window MApplicationWindow * m_window; // MApplicationPage -derived page MainPage * m_page; }; MyApplication::MyApplication(int & argc, char ** argv) : MApplication(argc, argv) { // Use the LazyShutdown mode setPrestartMode(M::LazyShutdown); m_window = new MApplicationWindow; m_window->show(); m_page = new MApplicationPage; m_page->appear(); // Run activateWidgets() here to setup things // if app is NOT in the prestarted state, otherwise it // will be called from the handler method. if (!isPrestarted()) { m_page->activateWidgets(); } } void MyApplication::releasePrestart() { // Your stuff here m_page->activateWidgets(); // Call the default implementation to show the window. MApplication::releasePrestart(); } void MyApplication::restorePrestart() { // Your stuff here m_page->deactivateAndResetWidgets(); // Call the default implementation to hide the window. MApplication::restorePrestart(); } MyApplication::~MyApplication() { delete m_window; delete m_page; } int main(int argc, char ** argv) { MyApplication app(argc, argv); return app.exec(); }
Copyright © 2010 Nokia Corporation | MeeGo Touch |