为了避免耗尽电量,闲置的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
公众号推荐: