爲了避免耗盡電量,閒置的Android設備很快就會入睡。但是,有時候應用程序需要喚醒屏幕或CPU並保持清醒狀態才能完成某些工作。
你採取的方法取決於你的應用程序的需求。然而,一般的經驗法則是,您應該爲您的應用使用最輕量級的方法,以儘量減少您的應用對系統資源的影響。以下各節介紹如何處理設備的默認睡眠行爲與您的應用程序的要求不兼容的情況。
替代使用喚醒鎖
在嚮應用程序添加wakelock支持之前,請考慮您的應用程序的用例是否支持以下其中一種替代解決方案:
- 如果您的應用正在執行長時間運行的HTTP下載,請考慮使用 DownloadManager。
- 如果您的應用正在同步來自外部服務器的數據,請考慮創建 同步適配器。
- 如果您的應用依賴後臺服務,請考慮使用 JobScheduler或 Firebase雲消息傳遞以特定間隔觸發這些服務。
保持屏幕開啓
某些應用需要保持屏幕打開狀態,例如遊戲或電影應用。做到這一點的最好方法是 FLAG_KEEP_SCREEN_ON 在你的活動中使用(並且只能在活動中使用,而不能在服務或其他應用程序組件中使用)。例如:
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
這種方法的優點是,不像喚醒鎖定(討論中 保持對CPU),它不需要特殊的權限,平臺正確管理用戶應用程序之間移動,而無需您的應用程序不必擔心釋放未使用的資源。
另一種實現此方法的方法是在應用程序的佈局XML文件中,使用 android:keepScreenOn屬性:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true">
...
</RelativeLayout>
使用android:keepScreenOn="true"相當於使用 FLAG_KEEP_SCREEN_ON。您可以使用最適合您應用的方法。在您的活動中以編程方式設置標誌的優點是,它可讓您選擇稍後以編程方式清除標誌,從而允許屏幕關閉。
注意:FLAG_KEEP_SCREEN_ON 除非不希望屏幕繼續保留在正在運行的應用程序中(例如,如果希望屏幕在一段時間不活動後超時),則不需要清除該 標誌。窗口管理器負責確保在應用程序進入後臺或返回前臺時發生正確的事情。但是如果你想明確地清除標誌並因此允許屏幕再次關閉,請使用clearFlags(): getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)。
保持CPU處於開啓狀態
如果您需要保持CPU運行才能在設備進入睡眠狀態之前完成某些工作,則可以使用PowerManager稱爲喚醒鎖的系統服務功能。喚醒鎖定允許您的應用程序控制主機設備的電源狀態。
創建和保持喚醒鎖可能會對主機設備的電池壽命產生巨大影響。因此,只有在嚴格需要的情況下才應使用喚醒鎖,並儘可能縮短時間。例如,您絕不應該在活動中使用喚醒鎖。如上所述,如果您想讓屏幕保持在您的活動中,請使用 FLAG_KEEP_SCREEN_ON。
使用喚醒鎖的一個合理案例可能是需要獲取喚醒鎖的後臺服務,以保證CPU在屏幕關閉時運行。不過,這種做法應該儘量減少,因爲它會影響電池壽命。
要使用喚醒鎖,第一步是將WAKE_LOCK 權限添加到應用程序的清單文件中:
<uses-permission android:name="android.permission.WAKE_LOCK" />
如果您的應用程序包含使用服務來做某些工作的廣播接收器,則可以通過使用允許設備保持喚醒的廣播接收器中WakefulBroadcastReceiver所述的 方式管理您的喚醒鎖 。這是首選的方法。如果你的應用不遵循這種模式,這裏是你如何直接設置喚醒鎖:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyWakelockTag");
wakeLock.acquire();
要釋放喚醒鎖,請致電 wakelock.release()。這會釋放您對CPU的聲明。一旦應用程序完成使用後釋放喚醒鎖定非常重要,以避免電池電量耗盡。
使用保持設備喚醒的廣播接收器
將廣播接收機與服務結合使用,可以管理後臺任務的生命週期。
A WakefulBroadcastReceiver是一種特殊類型的廣播接收器,負責創建和管理 PARTIAL_WAKE_LOCK您的應用。A WakefulBroadcastReceiver 將工作傳遞給一個Service (通常爲一個 IntentService),同時確保該設備在轉換中不會回到睡眠狀態。如果在將工作轉換爲服務時未保持喚醒鎖定,則可以在工作完成之前有效地讓設備重新進入休眠狀態。最終的結果是,應用程序未來可能無法完成工作,直到未來某個任意點,這不是您想要的。
使用a的第一步 WakefulBroadcastReceiver是將其添加到清單中,就像其他廣播接收器一樣:
<receiver android:name=".MyWakefulReceiver"></receiver>
以下代碼MyIntentService以該方法 開始startWakefulService()。這種方法是可比的startService(),除了WakefulBroadcastReceiver服務啓動時持有喚醒鎖。通過的意圖 startWakefulService() 持有一個額外的識別喚醒鎖
public class MyWakefulReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Start the service, keeping the device awake while the service is
// launching. This is the Intent to deliver to the service.
Intent service = new Intent(context, MyIntentService.class);
startWakefulService(context, service);
}
}
服務完成後,它會調用 MyWakefulReceiver.completeWakefulIntent() 釋放喚醒鎖。該 completeWakefulIntent() 方法的參數具有與以下內容相同的意圖WakefulBroadcastReceiver:
public class MyIntentService extends IntentService {
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
// Do the work that requires your app to keep the CPU running.
// ...
// Release the wake lock provided by the WakefulBroadcastReceiver.
MyWakefulReceiver.completeWakefulIntent(intent);
}
}
Lastest Update:2018.04.24
聯繫我
QQ:94297366
微信打賞:https://pan.baidu.com/s/1dSBXk3eFZu3mAMkw3xu9KQ
公衆號推薦: