Bagikan melalui


Manajemen daya dengan API siklus hidup aplikasi

API siklus hidup aplikasi di SDK Aplikasi Windows menyediakan sekumpulan API manajemen daya di namespace Microsoft.Windows.System.Power. API ini memberikan visibilitas tentang bagaimana aplikasi memengaruhi status daya perangkat, dan mereka memungkinkan aplikasi untuk membuat keputusan cerdas tentang penggunaan sumber daya. Misalnya, aplikasi mungkin menggunakan API ini untuk menunda tugas latar belakang intensif sumber daya saat perangkat berjalan dengan daya baterai.

API manajemen daya menggunakan model berbasis panggilan balik yang mirip dengan fungsi PowerSettingRegisterNotification yang ada. Menggunakan model panggilan balik memperluas jangkauan API ke semua aplikasi, termasuk aplikasi latar belakang, aplikasi headless, dan lainnya.

Prasyarat

Untuk menggunakan API siklus hidup aplikasi di SDK Aplikasi Windows:

  1. Unduh dan instal rilis terbaru SDK Aplikasi Windows. Untuk informasi selengkapnya, lihat Mulai menggunakan WinUI.
  2. Ikuti instruksi untuk Membuat proyek WinUI 3 pertama Anda atau untuk menggunakan SDK Aplikasi Windows dalam proyek yang ada.

Berlangganan dan merespons peristiwa

Contoh berikut menunjukkan cara berlangganan dan merespons peristiwa PowerManager . Kode ini berlangganan peristiwa BatteryStatusChanged selama startup. Aplikasi kemudian merespons perubahan dengan memeriksa tingkat daya saat ini dan menyesuaikan penggunaan sumber dayanya dengan tepat. Misalnya, jika baterai habis pada status daya rendah, aplikasi mungkin menukar pekerjaan latar belakang yang tidak penting.

Catatan

Aplikasi dapat mendaftar dan membatalkan pendaftaran untuk peristiwa ini kapan saja, tetapi sebagian besar aplikasi akan ingin mengatur panggilan balik di WinMain yang bertahan selama aplikasi terus berjalan.

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
}

Mengonfigurasi logika aplikasi berdasarkan beberapa nilai status

Peristiwa PowerManager relatif rendah, dan dalam beberapa skenario, satu penanganan aktivitas yang dipanggil mungkin tidak memberikan informasi yang cukup bagi aplikasi untuk memutuskan cara berperilaku. Dalam contoh ini, peristiwa PowerSupplyStatusChanged dapat dipanggil ketika perangkat terputus dari daya. Dalam hal ini, aplikasi harus memeriksa status baterai saat ini sebelum memutuskan cara melanjutkan.

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

Periksa status layar

Kelas PowerManager menawarkan informasi tentang status perangkat lain yang relevan dengan penggunaan daya aplikasi. Misalnya, aplikasi dapat menonaktifkan pemrosesan grafis saat tampilan perangkat dimatikan.

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

Berhenti berlangganan dari peristiwa

Aplikasi dapat mendaftar dan membatalkan pendaftaran pemberitahuan selama siklus hidupnya. Gunakan sistem manajemen pendaftaran peristiwa pilihan bahasa Anda jika aplikasi Anda tidak perlu menerima pemberitahuan status daya selama seluruh siklus hidupnya.

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