發布日期:
Android 11 (API 級別 30) - Thermal API
Android 12 (API 級別 31) - NDK API
(預先發布版) Android 15 (DP1) - getThermalHeadroomThresholds()
應用程式的潛在效能會受限於 細分功能,切身相關的特性包括天氣、近期使用情況 和裝置的熱力設計裝置只能維持最高等級 執行效能有限的時間,然後才開始調節溫度。一把鑰匙 導入目標,應該在沒有提示的情況下達成成效目標 。使用 Thermal API 即可讓 用於裝置專屬的最佳化設定此外,執行效能偵錯時 瞭解裝置的熱力狀態是否限制效能 非常重要
遊戲引擎通常會提供執行階段效能參數,可調整 執行工作負載舉例來說,您可以將這些參數 工作站執行緒的數量、大型與小型核心的工作站執行緒相依性, GPU 擬真度選項和 framebuffer 解析度。在 Unity Engine 中 開發人員可以調整工作負載品質, 設定 使用 Adaptive Performance 外掛程式。 如果是 Unreal Engine,請使用擴充性設定進行調整 以動態方式評估品質等級
當裝置靠近不安全的熱力狀態時,遊戲就能避免 藉此減少工作負載量。為了避免 此時,您應該監控裝置的熱力狀態,並主動監控 調整遊戲引擎工作負載裝置過熱後,工作負載必須 降溫低於永續性等級以消滅熱。更新後 當熱力上升空間進入安全等級時,遊戲就能 請務必調整畫質設定,並確保畫質穩定 以獲得最佳的播放時間
您可以藉由輪詢
getThermalHeadroom
敬上
方法。這個方法可預測裝置可維持目前狀態的時間長度
效能等級,避免過熱如果時間少於
遊戲應該將工作負載減少為
實踐永續發展理念舉例來說,遊戲可以改用較小的核心,
或低擬真度
取得熱力管理員
如要使用 Thermal API,請先取得 Thermal Manager
C++
AThermalManager* thermal_manager = AThermal_acquireManager();
Java
PowerManager powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
預測熱力上升空間 x 秒,進一步控制
您可以使用 目前工作負載這樣您就能更精細地控管設定 並有更多時間 便是減少工作負載來防止 實施熱節流
結果範圍從 0.0f (無調節,THERMAL_STATUS_NONE
) 至 1.0f
(大幅節流,THERMAL_STATUS_SEVERE
)。
如果遊戲的影像品質等級不同,可以遵照我們的
熱力上升空間準則。
C++
float thermal_headroom = AThermal_getThermalHeadroom(10);
ALOGI("ThermalHeadroom in 10 sec: %f", thermal_headroom);
Java
float thermalHeadroom = powerManager.getThermalHeadroom(10);
Log.d("ADPF", "ThermalHeadroom in 10 sec: " + thermalHeadroom);
或者,參考熱力狀態來取得說明
每個裝置型號的設計可能不同。部分裝置或許可以 分散暖氣,以便承受較高溫上升空間 然後受到限制如果想要閱讀經過簡化的 熱力上升空間,可以檢查熱力狀態 目前裝置的熱力上升空間值。
C++
AThermalStatus thermal_status = AThermal_getCurrentThermalStatus(thermal_manager);
ALOGI("ThermalStatus is: %d", thermal_status);
Java
int thermalStatus = powerManager.getCurrentThermalStatus();
Log.d("ADPF", "ThermalStatus is: " + thermalStatus);
在熱力狀態變更時收到通知
您也可以避免輪詢 thermalHeadroom
,直到 thermalStatus
命中為止
特定等級 (例如:THERMAL_STATUS_LIGHT
)。
如要這麼做,您可以註冊回呼,讓系統在
狀態已變更。
C++
int result = AThermal_registerThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
// failed, check whether you have previously registered callback that
// hasn’t been unregistered
}
Java
// PowerManager.OnThermalStatusChangedListener is an interface, thus you can
// also define a class that implements the methods
PowerManager.OnThermalStatusChangedListener listener = new
PowerManager.OnThermalStatusChangedListener() {
@Override
public void onThermalStatusChanged(int status) {
Log.d("ADPF", "ThermalStatus changed: " + status);
// check the status and flip the flag to start/stop pooling when
// applicable
}
};
powerManager.addThermalStatusListener(listener);
請記得在完成後移除事件監聽器
C++
int result = AThermal_unregisterThermalStatusListener(thermal_manager, callback);
if ( result != 0 ) {
// failed, check whether the callback has been registered previously
}
Java
powerManager.removeThermalStatusListener(listener);
清除
完成後,請清除您取得的 thermal_manager。 如果您使用 Java,則 PowerManager 參照可自動為垃圾檔案進行垃圾處理 系統但如果您是透過 JNI 使用 Java API,且 保留一個參考資料,請記得清除參照!
C++
AThermal_releaseManager(thermal_manager);
如需在原生 C++ 遊戲中實作 Thermal API 的完整指南, C++ API (NDK API) 和 Java API (透過 JNI),請參閱 「適應性程式碼研究室」中的 Thermal API 一節 專區。
熱力上升空間規範
您可以藉由輪詢
getThermalHeadroom
敬上
方法。這個方法可預測裝置可維持目前狀態的時間長度
成效等級才會顯示為 THERMAL_STATUS_SEVERE
。
舉例來說,如果 getThermalHeadroom(30)
傳回 0.8,就表示在 30 中
進步空間預計會達到 0.8,距離 0.2
防止過度節流,甚至是 1.0如果時間少於
即可讓遊戲達成永續發展
第二,自訂角色只能
套用至專案或機構舉例來說,遊戲可以降低影格速率、低保真度
以減少網路連線能力
過熱狀態與意義
- 如果裝置沒有溫度節流:
- 有部分節流問題,但沒有對效能造成重大影響:
- 發生會影響效能的重大節流設定:
Thermal API 的裝置限制
Thermal API 有一些已知限製或額外規定, 瞭解如何在較舊的裝置上實作 Thermal API。限制和方式 方法如下:
- 請勿太常呼叫
GetThermalHeadroom()
API。這麼做 結果,API 會傳回 NaN呼叫頻率上限為每秒一次。 - 如果
GetThermalHeadroom()
的初始值為 NaN,則 API 不會 可用的裝置 - 如果
GetThermalHeadroom()
傳回高價值 (例如:0.85 以上) 且GetCurrentThermalStatus()
仍會傳回THERMAL_STATUS_NONE
,表示狀態是 可能沒有更新。使用經驗法則估算正確的熱節流 或是只使用getThermalHeadroom()
,而不使用getCurrentThermalStatus()
。
經驗法則範例:
- 檢查系統是否支援 Thermal API。
isAPISupported()
會檢查 第一個呼叫getThermalHeadroom
以確保其並非 0 或 NN,並且 如果第一個值是 0 或 NaN,就會略過 API。 - 如果
getCurrentThermalStatus()
傳回的值不是THERMAL_STATUS_NONE
,裝置目前受到熱節限制。 - 如果
getCurrentThermalStatus()
持續傳回THERMAL_STATUS_NONE
,就會 但不一定代表裝置沒有受到熱節限制。 表示裝置不支援getCurrentThermalStatus()
。 檢查getThermalHeadroom()
的傳回值,確保 裝置。 - 如果
getThermalHeadroom()
傳回 > 的值1.0,狀態 但實際上是THERMAL_STATUS_SEVERE
以上,立即減少工作負載 維持較少工作負載,直到getThermalHeadroom()
傳回的值較低 - 如果
getThermalHeadroom()
傳回 0.95 值,狀態 但實際上是THERMAL_STATUS_MODERATE
以上,請立即減少工作負載 並隨時留意 - 如果
getThermalHeadroom()
傳回 0.85 值,狀態 其實是THERMAL_STATUS_LIGHT
,請密切留意並減少工作負載 可以的話
虛擬程式碼:
bool isAPISupported() {
float first_value_of_thermal_headroom = getThermalHeadroom();
if ( first_value_of_thermal_headroom == 0 ||
first_value_of_thermal_headroom == NaN ) {
// Checked the thermal Headroom API's initial return value
// it is NaN or 0,so, return false (not supported)
return false;
}
return true;
}
if (!isAPISupported()) {
// Checked the thermal Headroom API's initial return value, it is NaN or 0
// Don’t use the API
} else {
// Use thermalStatus API to check if it returns valid values.
if (getCurrentThermalStatus() > THERMAL_STATUS_NONE) {
// The device IS being thermally throttled
} else {
// The device is not being thermally throttled currently. However, it
// could also be an indicator that the ThermalStatus API may not be
// supported in the device.
// Currently this API uses predefined threshold values for thermal status
// mapping. In the future you may be able to query this directly.
float thermal_headroom = getThermalHeadroom();
if ( thermal_headroom > 1.0) {
// The device COULD be severely throttled.
} else if ( thermal_headroom > 0.95) {
// The device COULD be moderately throttled.
} else if ( thermal_headroom > 0.85) {
// The device COULD be experiencing light throttling.
}
}
}
圖: