Sailfish OS定时器长时间运行

引言


通常,在应用程序中实现任何逻辑时,需要在特定时间段后触发特定功能。 此类需求最明显的例子是计时器应用程序。 例如, cooktimerSaildoro

一篇文章所述,要将计时器添加到Sailfish OS上的应用程序,可以使用标准Timer元素或其C ++对应的QTimer 。 但是,默认情况下,由于设备可能进入睡眠状态,因此这些计时器的操作会长时间暂停。 上面提到的两个应用程序的开发人员都面临这个问题。

本文介绍了一种标准的方法,但是遗憾的是,没有记录的方法来处理Sailfish OS的这种行为。

起点


首先,我们将考虑Sailfish OS的“抽象”应用程序,该应用程序需要长时间运行某些功能。 同时,不是在QML代码中描述计时器操作,而是在C ++类中描述:

标头
 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; //    }; 


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


此类的对象必须在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(); } 


如引言中所述,使用这种方法,计时器可能会暂停很长一段时间。

解决方案


在开发人员的邮件列表中提出了防止计时器入睡的第一种选择,该方法在Cooktimer应用程序中扎根。 建议在此处显式设置一个额外的计时器,该计时器每分钟调用D-Bus方法req_display_cancel_blanking_pause来防止设备进入睡眠状态。 显然,这样的实现不是最佳且麻烦的。 首先,使用这种方法时,设备的电池电量消耗更快。 其次,次要代码出现在项目中可以避免。

而且您可以避免使用辅助代码,因为Sailfish OS已经提供了两种可能的解决方案: ScreenBlankKeepAlive元素。

使用第一种方法意味着屏幕始终处于活动状态。 这是一种有效但简单的方法,可以积极消耗设备的电池电量。 因此,可以使用它,但使用范围有限。

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

反过来,使用KeepAlive元素是一种更民主的方法。 在较小程度上,它会消耗电池电量,因为它无法使设备的屏幕始终保持打开状态,同时,它要么不允许设备进入深度睡眠状态,要么在某个时间点将其唤醒,因此计时器将继续工作很长一段时间。

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

值得注意的是,原则上所有上述三种方法的操作都是对D-Bus的系统方法的一种常规吸引,这在先前的文章中已有讨论。

结论


在本简短说明中,介绍了三种防止设备深度入睡的可能方法。 我们可以得出结论,对于后台任务(例如计时器),最好使用KeepAlive元素,如果需要不断向用户显示信息,则可以使用ScreenBlank

Source: https://habr.com/ru/post/zh-CN413389/


All Articles