Delen via


Energiebeheer met de levenscyclus-API voor apps

De api voor de levenscyclus van apps in de Windows App SDK biedt een set energiebeheer-API's in de microsoft.Windows.System.Power-naamruimte . Deze API's bieden inzicht in de invloed van een app op de energiestatus van het apparaat en stellen de app in staat intelligente beslissingen te nemen over resourcegebruik. Een app kan deze API bijvoorbeeld gebruiken om resource-intensieve achtergrondtaken uit te stellen terwijl het apparaat wordt uitgevoerd op accustroom.

De energiebeheer-API's maken gebruik van een callback-model dat vergelijkbaar is met de bestaande PowerSettingRegisterNotification-functie . Het gebruik van een callback-model breidt het bereik van de API uit naar alle apps, inclusief achtergrond-apps, headless apps en andere.

Vereiste voorwaarden

De levenscyclus-API voor apps gebruiken in de Windows App SDK:

  1. Download en installeer de nieuwste versie van de Windows App SDK. Zie Aan de slag met WinUI voor meer informatie.
  2. Volg de instructies voor Uw eerste WinUI 3-project maken of om de Windows App SDK te gebruiken in een bestaand project.

Abonneren en reageren op gebeurtenissen

In het volgende voorbeeld ziet u hoe u zich abonneert en reageert op PowerManager-gebeurtenissen . Deze code abonneert zich op de gebeurtenis BatteryStatusChanged tijdens het opstarten. De app reageert vervolgens op wijzigingen door het huidige energieniveau te controleren en het resourcegebruik op de juiste manier aan te passen. Als de batterij bijvoorbeeld ontlaadt met een lage energiestatus, kan de app eventuele niet-kritieke achtergrondwerkzaamheden uitstellen.

Opmerking

Apps kunnen deze gebeurtenissen op elk gewenst moment registreren en de registratie ervan ongedaan maken, maar de meeste apps willen callbacks instellen in WinMain die blijven bestaan zolang de app blijft worden uitgevoerd.

BOOL bWorkInProgress;
winrt::event_token batteryToken;
winrt::event_token powerToken;
winrt::event_token powerSourceToken;
winrt::event_token chargeToken;
winrt::event_token dischargeToken;

void RegisterPowerManagerCallbacks()
{
    batteryToken = PowerManager::BatteryStatusChanged([&](
        const auto&, winrt::Windows::Foundation::IInspectable obj) { OnBatteryStatusChanged(); });
    powerToken = PowerManager::PowerSupplyStatusChanged([&](
        const auto&, winrt::Windows::Foundation::IInspectable obj) { OnPowerSupplyStatusChanged(); });
    powerSourceToken = PowerManager::PowerSourceKindChanged([&](
        const auto&, winrt::Windows::Foundation::IInspectable obj) { OnPowerSourceKindChanged(); });
    chargeToken = PowerManager::RemainingChargePercentChanged([&](
        const auto&, winrt::Windows::Foundation::IInspectable obj) { OnRemainingChargePercentChanged(); });
    dischargeToken = PowerManager::RemainingDischargeTimeChanged([&](
        const auto&, winrt::Windows::Foundation::IInspectable obj) { OnRemainingDischargeTimeChanged(); });

    if (batteryToken && powerToken && powerSourceToken && chargeToken && dischargeToken)
    {
        OutputMessage(L"Successfully registered for state notifications");
    }
    else
    {
        OutputMessage(L"Failed to register for state notifications");
    }
}

void OnBatteryStatusChanged()
{
    const size_t statusSize = 16;
    WCHAR szStatus[statusSize];
    wmemset(&(szStatus[0]), 0, statusSize);

    BatteryStatus batteryStatus = PowerManager::BatteryStatus();
    int remainingCharge = PowerManager::RemainingChargePercent();
    switch (batteryStatus)
    {
    case BatteryStatus::Charging:
        wcscpy_s(szStatus, L"Charging");
        break;
    case BatteryStatus::Discharging:
        wcscpy_s(szStatus, L"Discharging");
        break;
    case BatteryStatus::Idle:
        wcscpy_s(szStatus, L"Idle");
        break;
    case BatteryStatus::NotPresent:
        wcscpy_s(szStatus, L"NotPresent");
        break;
    }

    OutputFormattedMessage(
        L"Battery status changed: %s, %d%% remaining", 
        szStatus, remainingCharge);
    DetermineWorkloads();
}

void OnPowerSupplyStatusChanged()
{
//...etc
}

App-logica configureren op basis van meerdere statuswaarden

PowerManager gebeurtenissen zijn betrekkelijk laagdrempelig, en in sommige scenario's biedt het aanroepen van één enkele gebeurtenis-handler mogelijk niet genoeg informatie voor de app om te bepalen hoe te handelen. In dit voorbeeld kan de gebeurtenis PowerSupplyStatusChanged worden aangeroepen wanneer het apparaat is losgekoppeld van stroom. In dat geval moet de app de huidige batterijstatus controleren voordat wordt bepaald hoe u doorgaat.

void DetermineWorkloads()
{
    BatteryStatus batteryStatus = PowerManager::BatteryStatus();
    int remainingCharge = PowerManager::RemainingChargePercent();
    PowerSupplyStatus powerStatus = PowerManager::PowerSupplyStatus();
    PowerSourceKind powerSource = PowerManager::PowerSourceKind();

    if ((powerSource == PowerSourceKind::DC 
        && batteryStatus == BatteryStatus::Discharging 
        && remainingCharge < 25)
        || (powerSource == PowerSourceKind::AC
        && powerStatus == PowerSupplyStatus::Inadequate))
    {
        // The device is not in a good battery/power state, 
        // so we should pause any non-critical work.
        PauseNonCriticalWork();
    }
    else if ((batteryStatus != BatteryStatus::Discharging && remainingCharge > 75)
        && powerStatus != PowerSupplyStatus::Inadequate)
    {
        // The device is in good battery/power state,
        // so let's kick of some high-power work.
        StartPowerIntensiveWork();
    }
}

Schermstatus controleren

De PowerManager-klasse biedt informatie over andere apparaatstatussen die relevant zijn voor het energieverbruik van een app. Apps kunnen bijvoorbeeld grafische verwerking uitschakelen wanneer de weergave van het apparaat is uitgeschakeld.

void OnDisplayStatusChanged()
{
    const size_t statusSize = 16;
    WCHAR szStatus[statusSize];
    wmemset(&(szStatus[0]), 0, statusSize);

    DisplayStatus displayStatus = PowerManager::DisplayStatus();
    switch (displayStatus)
    {
    case DisplayStatus::Dimmed:
        wcscpy_s(szStatus, L"Dimmed");
        break;
    case DisplayStatus::Off:
        wcscpy_s(szStatus, L"Off");
        break;
    case DisplayStatus::On:
        wcscpy_s(szStatus, L"On");
        break;
    }

    OutputFormattedMessage(
        L"Display status changed: %s", szStatus);
    if (displayStatus == DisplayStatus::Off)
    {
        // The screen is off, let's stop rendering foreground graphics,
        // and instead kick off some background work now.
        StopUpdatingGraphics();
        StartDoingBackgroundWork();
    }
}

Afmelden voor gebeurtenissen

Apps kunnen tijdens hun levenscyclus meldingen registreren en de registratie ervan opheffen. Gebruik het voorkeurssysteem voor gebeurtenisregistratiebeheer van uw taal als uw app tijdens de volledige levenscyclus geen energiestatusmeldingen hoeft te ontvangen.

void UnregisterPowerManagerCallbacks()
{
    OutputMessage(L"Unregistering state notifications");
    PowerManager::BatteryStatusChanged(batteryToken);
    PowerManager::PowerSupplyStatusChanged(powerToken);
    PowerManager::PowerSourceKindChanged(powerSourceToken);
    PowerManager::RemainingChargePercentChanged(chargeToken);
    PowerManager::RemainingDischargeTimeChanged(dischargeToken);
}