Sailfish OS Timer-Betrieb über lange Intervalle

Einführung


Sehr oft muss bei der Implementierung einer Logik in der Anwendung nach einer bestimmten Zeit eine bestimmte Funktion ausgelöst werden. Das offensichtlichste Beispiel für einen solchen Bedarf ist eine Zeitgeberanwendung. Zum Beispiel Cooktimer oder Saildoro .

Wie in einem früheren Artikel erwähnt, können Sie zum Hinzufügen eines Timers zu einer Anwendung unter Sailfish OS das Standard- Timer Element oder dessen C ++ - Gegenstück QTimer . Standardmäßig wird der Betrieb dieser Timer jedoch für längere Zeit unterbrochen, da das Gerät möglicherweise in den Ruhezustand wechselt. Die Entwickler der beiden oben genannten Anwendungen haben sich gerade diesem Problem gestellt.

In diesem Artikel wird eine standardmäßige, aber leider nicht dokumentierte Methode zur Behandlung dieses Verhaltens von Sailfish OS vorgestellt.

Ausgangspunkt


Als Ausgangspunkt betrachten wir eine "abstrakte" Anwendung für Sailfish OS, die den Betrieb einiger Funktionen nach einer langen Zeit erfordert. Gleichzeitig wird die Timer-Operation nicht im QML-Code, sondern in einer C ++ - Klasse beschrieben:

Header
 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; //    }; 


Quelle
 #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(); //     } 


Ein Objekt dieser Klasse muss in QML registriert sein:

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(); } 


Bei diesem Ansatz kann, wie in der Einleitung erwähnt, ein Timer für längere Zeit pausieren.

Lösung


Die erste Option, um das Einschlafen des Timers zu verhindern, wurde in der Mailingliste der Entwickler vorgeschlagen und in der Cooktimer-Anwendung verwurzelt. Hier wird vorgeschlagen, explizit einen zusätzlichen Timer einzurichten, der einmal pro Minute die D-Bus-Methode req_display_cancel_blanking_pause , um ein Einschlafen des Geräts zu verhindern. Offensichtlich ist eine solche Implementierung nicht optimal und umständlich. Erstens wird bei diesem Ansatz der Akku des Geräts schneller leer. Zweitens erscheint im Projekt ein kleiner Code, der vermieden werden kann.

Sie können die Verwendung von Sekundärcode vermeiden, da Sailfish OS bereits zwei mögliche Lösungen für das Problem bietet: ScreenBlank und KeepAlive Elemente.

Die Verwendung des ersten Ansatzes impliziert einen ständig aktiven Bildschirm. Dies ist ein funktionierender, aber unkomplizierter Ansatz, bei dem der Akku des Geräts aktiv verbraucht wird. Somit kann es verwendet werden, jedoch in einem begrenzten Bereich von Situationen.

 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 //    } } 

Die Verwendung des KeepAlive Elements ist wiederum ein demokratischerer Ansatz. In geringerem Maße verbraucht es Batteriestrom, da der Bildschirm des Geräts nicht ständig eingeschaltet bleibt und gleichzeitig das Gerät entweder nicht in den Tiefschlaf versetzt oder zu einem bestimmten Zeitpunkt aufgeweckt wird, sodass der Timer weiterarbeitet lange Zeiträume.

 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 //       } } 

Es ist anzumerken, dass die Funktionsweise aller drei genannten Methoden im Prinzip eine regelmäßige Berufung auf die Systemmethoden von D-Bus darstellt, die in einem der vorhergehenden Artikel erörtert wurden.

Fazit


In diesem kurzen Hinweis werden drei Möglichkeiten beschrieben, wie Sie verhindern können, dass das Gerät tief einschlafen kann. Wir können daraus schließen, dass es für Hintergrundaufgaben (z. B. einen Timer) optimal ist, das KeepAlive Element zu verwenden. Wenn dem Benutzer ständig Informationen angezeigt werden müssen, wird ScreenBlank .

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


All Articles