Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android官方開發文檔Training系列課程中文版:管理設備的睡眠狀態

Android官方開發文檔Training系列課程中文版:管理設備的睡眠狀態

編輯:關於Android編程

原文地址: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 {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
  }
  ...
}

這種方法的優勢在於:它不要指定特殊權限,系統會將APP之間的狀態切換處理好,也不需要擔心有關釋放無用資源的問題。

另一個實現方式就是在布局文件中使用android:keepScreenOn屬性:


    ...

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的權限:

如果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用法的第一步就是將其添加到清單文件中,與其它廣播接收器的添加方式一樣:

第二步就是使用startWakefulService()方法來啟動MyIntentService。這個方法除了在啟動時WakefulBroadcastReceiver持有了一個WakeLock外,其它的都與startService()很相似。在startWakefulService()中所使用的Intent被隱式的攜帶了一個WakeLock。

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()將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");
    }
    @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);
    }
}
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved