Android保持设备唤醒

Contents

保持设备唤醒... 1

使用wakelock之外的选择... 1

保持屏幕亮... 1

保持CPU运行... 2

用BroadcastReceiver保持设备唤醒... 2

 

保持设备唤醒

为了避免电量流失,Android设备进入闲置状态后很快就会睡眠。然而,有时应用需要设备保持屏幕或者CPU处于唤醒状态一直到完成某项工作。

应用的需求不同采取的策略也不同。然而一般原则是尽量使用轻量级的方法,最小化应用对系统资源的使用。下面的段落描述了如何处理这种情况,即设备默认的睡眠行为和你的应用的需求不兼容。

使用wakelock之外的选择

在应用使用wakelock前,考虑是否你的需求满足下面几种不建议用wakelock的情况:

  • 长时间运行的HTTP下载,考虑用DownloadManager。
  • 应用需要从外部服务器同步数据,考虑用sync adapter。
  • 如果应用依赖于后台服务,考虑用JobScheduler或者FCM定期触发服务。

保持屏幕亮

一些应用需要保持屏幕亮,比如游戏或视频应用。最好的办法是在Activity里使用FLAG_KEEP_SCREEN_ON(只在Activity,而不在Service或其他应用组件中使用wakelock)。例如:

class MainActivity : Activity() {

   
override fun onCreate(savedInstanceState: Bundle?) {
       
super.onCreate(savedInstanceState)
        setContentView(R.layout.activity
_main)
        window.addFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
    }
}

这种策略的好处是,不像使用wakelock,他不需要特殊权限,平台可以负责管理用户在应用之间的切换,应用不用关心释放资源的事情。

另一个实现方式是在应用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,对你的应用来说,哪个好用就用哪个。在Activity中设置这个属性的好处是,如果不需要了,你可以在后面的程序中选择关掉它,这样屏幕就不会长亮了。

注意:你不需要清除FLAG_KEEP_SCREEN_ON标志,除非你不再需要屏幕保持长亮(例如,你希望在一定时间不活动之后屏幕时间超时)。当应用进入后台运行或者重新进入前台,Window Manager会负责屏幕的亮暗。但是如果你需要显式清除这项标志,以允许屏幕重新关掉,用clearFlags():getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)。

保持CPU运行

如果你希望设备睡去之前保持CPU运行以完成某项工作,可以用PowerManager的系统服务功能wakelock。Wakelock允许你控制主机的电源状态。

创建和持有wakelock对主机的电池影响巨大。所以只有在非常必要的时候使用wakelock,并且持有时间尽可能短。例如,你永远不需要在Activity中使用wakelock。如上文所述,如果想在Activty中亮,使用FLAG_KEEP_SCREEN_ON。

一个合理的使用wakelock的情况是,后台服务需要获取wakelock,在屏幕关的时候保持CPU运行。再次强调,尽可能减少使用wakelock的时间,因为太耗电了。

要使用wakelock,先在应用manifest文件中加入权限:

<uses-permission android:name="android.permission.WAKE_LOCK" />

如果你的应用包含一个BroadcastReceiver,启动一个服务做一些操作,可以通过WakefulBroadcastReceiver管理你的wakelock。

PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);

WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,

        "MyApp::MyWakelockTag");

wakeLock.acquire();

要释放wakelock,调用wakelock.release()。及时释放wakelock很重要。

BroadcastReceiver保持设备唤醒

用BroadcastReceiver和Service管理后台任务的生命周期。

WakefulBroadcastReceiver是一个特殊的BroadcastReceiver,他负责为应用创建和管理PARTIAL_WAKE_LOCK。WakefulBroadcastReceiver把工作传给Service(一般是IntentService),同时保证设备在传输过程中不进入睡眠模式。如果你在传输过程中不保持wakelock,有可能设备进入睡眠模式,而你的任务还没有完成。

使用WakefulBroadcastReceiver的第一步是把它添加到manifest中,就像其他BroadcastReceiver一样。

<receiver android:name=".MyWakefulReceiver"></receiver>

下面的代码用startWakefulService()启动了MyIntentService。相比startService(),这个方法在启动的时候持有一个wakelock。通过startWakefulService()传递的intent中有个extra,指定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()传递过来的一样。

猜你喜欢

转载自blog.csdn.net/yubing1015/article/details/85235431