Fonctionnement de la minuterie Sailfish OS sur de longs intervalles

Présentation


Très souvent, lors de l'implémentation d'une logique dans l'application, il est nécessaire de déclencher une certaine fonction après un certain laps de temps. L'exemple le plus évident d'un tel besoin est une application de minuterie. Par exemple, cooktimer ou Saildoro .

Comme mentionné dans un article précédent , pour ajouter un minuteur à une application sur Sailfish OS, vous pouvez utiliser l'élément Timer standard ou son homologue C ++, QTimer . Cependant, par défaut, le fonctionnement de ces minuteries est suspendu pendant de longues périodes en raison du fait que l'appareil peut se mettre en veille. Les développeurs des deux applications mentionnées ci-dessus viennent de rencontrer ce problème.

Cet article présente une manière standard, mais malheureusement non documentée, de gérer ce comportement de Sailfish OS.

Point de départ


Comme point de départ, nous considérerons une application "abstraite" pour Sailfish OS, qui nécessite le fonctionnement de certaines fonctionnalités après une longue période de temps. Dans le même temps, l'opération de temporisation n'est pas décrite dans le code QML, mais dans une classe C ++:

En-tête
 class TimerWrapper : public QObject { Q_OBJECT public: //    explicit TimerWrapper(QObject *parent = 0); ~TimerWrapper(); Q_INVOKABLE void start(int interval); //     Q_INVOKABLE void stop(); //     signals: void pomodoroFinished(int start, int end); //    void activeChanged(); //     private: QTimer *_timer; //   int _startTime; //    }; 


Source
 #include "timerwrapper.h" /** *  . */ TimerWrapper::TimerWrapper(QObject *parent) : QObject(parent) { _timer = new QTimer(this); //    _timer->setSingleShot(true); //     //           connect(_timer, &QTimer::timeout, [=]() { emit activeChanged(); eemit pomodoroFinished(_startTime, QDateTime::currentDateTime().toMSecsSinceEpoch()); }); } /** *  . */ TimerWrapper::~TimerWrapper() { delete _timer; _timer = nullptr; } /** *     . * @:param: interval -      */ void TimerWrapper::start(int interval) { _startTime = QDateTime::currentMSecsSinceEpoch(); //    _timer->start(interval); //   emit activeChanged(); //      } /** *    . */ void TimerWrapper::stop() { _timer->stop(); //   emit activeChanged(); //     } 


Un objet de cette classe doit être enregistré en QML:

main.cpp
 #ifdef QT_QML_DEBUG #include <QtQuick> #endif #include <QGuiApplication> #include <QQmlContext> #include <QQuickView> #include <QScopedPointer> #include <sailfishapp.h> #include "timerwrapper.h" int main(int argc, char *argv[]) { //    QScopedPointer<QGuiApplication> application(SailfishApp::application(argc, argv)); //      QScopedPointer<QQuickView> view(SailfishApp::createView()); //    QScopedPointer<TimerWrapper> timer(new TimerWrapper(view.data())); //    view->rootContext()->setContextProperty("timer", timer.data()); //     QML- view->setSource(SailfishApp::pathTo("qml/harbour-application.qml")); //   view->show(); //   return application->exec(); } 


Avec cette approche, comme mentionné dans l'introduction, une minuterie peut faire une pause pendant de longues périodes.

Solution


La première option pour empêcher la minuterie de s'endormir a été proposée dans la liste de diffusion des développeurs et a pris racine dans l'application cooktimer. Ici, il est proposé de configurer explicitement une minuterie supplémentaire, qui appelle une fois par minute la méthode D-Bus req_display_cancel_blanking_pause pour empêcher l'appareil de s'endormir. De toute évidence, une telle implémentation n'est pas optimale et lourde. Premièrement, lorsque vous utilisez cette approche, la batterie de l'appareil s'épuise plus rapidement. Deuxièmement, un code mineur apparaît dans le projet qui peut être évité.

Et vous pouvez éviter d'utiliser du code secondaire car Sailfish OS fournit déjà deux solutions possibles au problème: les éléments ScreenBlank et KeepAlive .

L'utilisation de la première approche implique un écran constamment actif. Il s'agit d'une approche fonctionnelle, mais simple, qui consomme activement la batterie de l'appareil. Ainsi, il peut être utilisé, mais dans un éventail limité de situations.

 import QtQuick 2.0 //       QML import Sailfish.Silica 1.0 //     Sailfish OS UI import Sailfish.Media 1.0 //      ScreenBlank ApplicationWindow //     { initialPage: Component { FirstPage { } } //     cover: Qt.resolvedUrl("cover/CoverPage.qml") //    ScreenBlank { //       id: screenBlank //    suspend: true //    } } 

À son tour, l'utilisation de l'élément KeepAlive est une approche plus démocratique. Dans une moindre mesure, il consomme de la batterie, car il ne garde pas l'écran de l'appareil constamment allumé, et en même temps, il ne permet pas à l'appareil de dormir profondément ou le réveille à un certain moment, de sorte que la minuterie continuera de fonctionner. de longues périodes de temps.

 import QtQuick 2.0 //       QML import Sailfish.Silica 1.0 //     Sailfish OS UI import org.nemomobile.keepalive 1.1 //      KeepAlive ApplicationWindow //     { initialPage: Component { FirstPage { } } //     cover: Qt.resolvedUrl("cover/CoverPage.qml") //    KeepAlive { //       id: keepAlive //    enabled: true //       } } 

Il convient de noter qu'en principe, le fonctionnement des trois méthodes mentionnées est un appel régulier aux méthodes de système de D-Bus, qui a été discuté dans l'un des articles précédents .

Conclusion


Dans cette courte note, trois façons possibles d'empêcher l'appareil de s'endormir profondément sont décrites. Nous pouvons conclure que pour les tâches d'arrière-plan (par exemple, une minuterie), il est optimal d'utiliser l'élément KeepAlive , et s'il est nécessaire d'afficher constamment des informations à l'utilisateur, puis ScreenBlank .

Source: https://habr.com/ru/post/fr413389/


All Articles