Partilhar via


Gerenciamento de energia com a API do ciclo de vida do aplicativo

A API de ciclo de vida do aplicativo no SDK de aplicativos do Windows fornece um conjunto de APIs de gerenciamento de energia no namespace Microsoft.Windows.System.Power . Essas APIs fornecem visibilidade sobre como um aplicativo afeta o estado de energia do dispositivo e permitem que o aplicativo tome decisões inteligentes sobre o uso de recursos. Por exemplo, um aplicativo pode usar essa API para adiar tarefas em segundo plano que consomem muitos recursos enquanto o dispositivo está sendo executado com bateria.

As APIs de gerenciamento de energia usam um modelo baseado em retorno de chamada semelhante à função PowerSettingRegisterNotification existente. A utilização de um modelo de callback estende o alcance da API a todas as aplicações, incluindo aplicações em segundo plano, aplicações sem interface gráfica e outras.

Pré-requisitos

Para usar a API de ciclo de vida do aplicativo no SDK do Aplicativo Windows:

  1. Transfira e instale a versão mais recente do SDK de Aplicações Windows. Para obter mais informações, consulte Introdução ao WinUI.
  2. Siga as instruções para criar seu primeiro projeto WinUI 3 ou para usar o SDK do aplicativo Windows em um projeto existente.

Subscrever e responder a eventos

O exemplo a seguir demonstra como subscrever e responder a eventos do PowerManager . Este código subscreve o evento BatteryStatusChanged durante o arranque. Em seguida, o aplicativo responde às alterações verificando o nível de energia atual e ajustando o uso de recursos adequadamente. Por exemplo, se a bateria for descarregada em um estado de baixa energia, o aplicativo poderá adiar qualquer trabalho em segundo plano não crítico.

Observação

As aplicações podem registar e cancelar o registo para esses eventos a qualquer momento, mas a maioria das aplicações procurará definir callbacks em WinMain que permaneçam enquanto a aplicação continuar a funcionar.

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
}

Configurar a lógica do aplicativo com base em vários valores de status

Os eventos de do PowerManager são de nível relativamente baixo e, em alguns cenários, um único manipulador de eventos, quando é chamado, pode não fornecer informações suficientes para o aplicativo decidir o comportamento. Neste exemplo, o evento PowerSupplyStatusChanged pode ser chamado quando o dispositivo é desconectado da alimentação. Nesse caso, o aplicativo deve verificar o status atual da bateria antes de decidir como proceder.

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

Verificar o estado do ecrã

A classe PowerManager oferece informações sobre outros estados do dispositivo relevantes para o uso de energia de um aplicativo. Por exemplo, as aplicações podem desativar o processamento gráfico quando o ecrã do dispositivo está desligado.

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

Cancelar inscrição em eventos

Os aplicativos podem se registrar e cancelar o registro para notificações durante seu ciclo de vida. Use o sistema de gerenciamento de registro de eventos preferido do seu idioma se o aplicativo não precisar receber notificações de status de energia durante todo o ciclo de vida.

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