Android官方开发文档Training系列课程中文版:管理设备的睡眠状态
原文地址:http://android.xsoftlab.net/training/scheduling/index.html
引言
當Android設備處于閑置狀態時,它的屏幕首先會變暗,接著會關閉屏幕,最后會將CPU關閉。這些舉措可以防止設備的電量迅速被耗盡。但是當APP需要的話,還是會有例外情況:
- 游戲類APP或者視頻類APP需要保持屏幕常亮。
- 有一部分APP或許不需要屏幕保持常亮,但是它們需要CPU繼續保持運轉,直到它們的任務執行完畢。
這節課主要學習如何在需要的時候保持設備的喚醒狀態而又不至于非常耗電。
保持設備的喚醒狀態
為了避免迅速將電量耗光,Android設備會在進入閑置狀態后緊接著進入睡眠狀態。不過,還是有一些例外情況的:它們需要保持屏幕常亮或者是保持CPU持續運轉狀態以便完成某些任務。
具體采用什么樣的方式這取決于APP的需求。不過,有一條規則就是盡量采取最輕量級的方法,盡可能少的消耗系統資源。
保持屏幕常亮
某些APP比如游戲類APP或者視頻類APP需要保持屏幕常亮。要做到這一點只需要在Activity中使用FLAG_KEEP_SCREEN_ON就可以,不過千萬不要在服務或者其它組件中使用該標志:
public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);}... }這種方法的優勢在于:它不要指定特殊權限,系統會將APP之間的狀態切換處理好,也不需要擔心有關釋放無用資源的問題。
另一個實現方式就是在布局文件中使用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的效果等同。你可以選擇最合適的方式。使用標志的優勢在于可以動態的清除該標志的狀態,以便于屏幕可以轉入關閉狀態。
Note: 除非可以肯定屏幕不再需要保持常亮,否則不需要我們自己專門去清除該標志。WindowManager會嚴格把關這些事情:APP轉入后臺時,APP轉入前臺時。但是如果你明確要清除該標志以便屏幕可以轉入關閉狀態,那么可以使用clearFlags():getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
保持CPU的運行
如果APP希望在系統轉入睡眠狀態之前完成一些事情,那么可以使用PowerManager系統服務中的WakeLock特性。WakeLock可以使APP控制設備的電源狀態。
因為持有WakeLock對象可以直接與電源交互,所以只能在必要的時候使用WakeLock。絕不要在Activity中使用WakeLock。就像上面說的那樣,如果希望保持屏幕常亮,只需要使用FLAG_KEEP_SCREEN_ON就可以。
使用WakeLock的合理場景就是后臺服務。再強調一次,使用時應當以最小限度使用該標志,因為它會直接影響到電池的電量。
如果要使用WakeLock,首先需要在清單文件中添加WakeLock的權限:
<uses-permission android:name="android.permission.WAKE_LOCK" />如果APP還包括了一個與服務做相關工作的廣播接收器,那么可以通過WakefulBroadcastReceiver來管理WakeLock。這是一種非常理想的方案。如果APP沒有那樣的情況,那么也可以使用下面的方法:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); Wakelock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyWakelockTag"); wakeLock.acquire();如果要釋放WakeLock,調用wakelock.release()就好。它會釋放你所持有的CPU資源。在任務完成后做這項工作是很重要的,因為這可以防止電池電量被迅速耗光。
使用WakefulBroadcastReceiver
廣播接收器與服務的結合使用非常易于管理后臺任務的生命周期。
WakefulBroadcastReceiver是一種特殊的廣播接收器:它可以創建并管理APP的PARTIAL_WAKE_LOCK。在設備即將轉入睡眠狀態時,WakefulBroadcastReceiver會將該信號發給服務(通常是IntentService)。如果在收到廣播后沒有持有WakeLock,那么可以在工作完成之前設備就會轉入睡眠狀態。這就會導致任務不能及時完成,這并不是我們想看到的。
WakefulBroadcastReceiver用法的第一步就是將其添加到清單文件中,與其它廣播接收器的添加方式一樣:
<receiver android:name=".MyWakefulReceiver"></receiver>第二步就是使用startWakefulService()方法來啟動MyIntentService。這個方法除了在啟動時WakefulBroadcastReceiver持有了一個WakeLock外,其它的都與startService()很相似。在startWakefulService()中所使用的Intent被隱式的攜帶了一個WakeLock。
public class MyWakefulReceiver extends WakefulBroadcastReceiver {@Overridepublic 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()將WakeLock釋放。completeWakefulIntent()方法使用了被WakefulBroadcastReceiver傳遞過來的Intent對象:
public class MyIntentService extends IntentService {public static final int NOTIFICATION_ID = 1;private NotificationManager mNotificationManager;NotificationCompat.Builder builder;public MyIntentService() {super("MyIntentService");}@Overrideprotected 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);} }總結
以上是生活随笔為你收集整理的Android官方开发文档Training系列课程中文版:管理设备的睡眠状态的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jar2exe 配置jre
- 下一篇: ATM小程序