很多朋友都抱怨Android机电量不行,没有iPhone的耐用,问我怎么解决。我首先恭喜你们拥有一颗发现的眼睛,电量不耐用是Android的通病。明明电量是iPhone的几倍,但是可能还没有它耐用,为什么?究其原因,就是Android手机本身系统和ios的系统是不一样的(因为没有开发手机驱动的经验,所以粗略提一下带过)。作为一个Android开发人员,如果都能到更好的电量优化,相信你的手机电量会更加耐用。
Android应用开发中存在很多比较耗电的特性。例如网络,定位,传感器等,同时关于一些关键的API的正确使用也是有效降低应用耗电的手段,例如BroadcastReceiver,AlarmManager,WakeLock等。
为了减少应用的损耗的电量,在代码实现中需要尽量避免无用操作代码的执行。当应用退到后台,一切的界面刷新都是没有意义而且浪费内存和电量的,广播接收器是一个典型的例子。如果应用中存在一个监听网络状态变化的广播接收器并会执行一些动作,例如弹出Toast提示用户网络环境的切换,那么当应用位于后台时,我们需要禁用掉这个提示功能,因为这时它不仅影响用户使用其他应用而且孩子啊后台默默地消耗着设备上本来就不多的电量,通常的做法是在界面onPause之后取消广播接收器的监听操作,同时根据具体业务需求选择当应用位于后台时是否禁用广播接收器,代码如下:
/**
* 是否禁用广播接收器
* @param isEnabled
* @param receiver
*/
private void enableBroadcastReceiver(boolean isEnabled,Class> receiver) {
PackageManager pm = getPackageManager();
ComponentName receiverName = new ComponentName(this,receiver);
int newState;
if(isEnabled) {
newState = PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
} else {
newState = PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
}
pm.setComponentEnabledSetting(receiverName,newState,PackageManager.DONT_KILL_APP);
}
Android 中的数据传输方式有很多种,常见的有:
无论哪种传输方式,为了更好地延长电池的使用时间,我们在使用过程中都需要重点关注两件事情
后台数据传输的管理:根据具体业务需求,严格限制应用位于后台时是否禁用某些数据传输,尽量能够避免无效的数据传输。
数据传输的频度问题:通过经验值或者数据统计的方法确定好数据传输的频度,避免冗余重复的数据传输,同时,数据传输过程中要压缩数据大小,合并网络请求,避免轮询等。
Android中常见的位置服务有两种:GPS定位和网络定位。GPS定位服务需要ACCESS_FINE_LOCATION权限,网络定位服务需要ACCESS_COARSE_LOCATION或者ACCESS_FINE_LOCATION权限。代码中使用位置服务时,通常需要关注一下几个方面。
private void disableLocaltionListener (LocationListener listener) {
LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.removeUpdates(listener);
}
位置更新监听频率的设定:根据具体的业务需求设置一个合适的更新频率值,通常需要在定位精度和耗电量之间综合考虑。Android SDK 提供了requestLocationUpdates 方法进行设置,这个方法有两个主要参数
多种位置服务的选择:Android系统为开发者提供了三种定位服务。
实际开发中需要综合考虑应用的具体需求在不同时机采用不同的定位服务,实际开发中很多会选择第三方的定位SDK,例如:百度定位,高德定位。因为这些SDK无论在定位时间,定位精度还是定位耗电量方面都作了专门的优化。
AlarmManager是Android SDK提供的一个唤醒API,它是系统级别的服务,可以在特定的时刻广播一个特定的Intent,这个PendingIntent可以用来启动Activity,Service或BroadcastReceive。例如后台上传统计信息,可以通过一个AlarmManager来定时检查是否满足条件并上传记录。AlarmManager提供了三个常用的方法。
AlarmManager的唤醒操作也是比较耗电的,通常情况下需要保证两次唤醒操作的时间间隔不要太短,在不需要使用唤醒功能的情况下尽早取消AlarmManager,否则应用会一直处于耗电状态。
WakeLock是为了保持设备处于唤醒状态的API,因为在某些情况下,即使用户长时间不与设备交互,仍然需要阻止设备进入休眠状态,从而保证良好的用户体验。WakeLock的锁类型又很多种,不同的锁类型对CPU,屏幕和键盘的影响不相同,具体情况如下:
WakeLock的使用很简单,语句如下:
PowerManager.WakeLock wakeLock = null;
// 获取唤醒锁
private void acquireWakeLock() {
if(null == wakeLock) {
PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE,"PlayService");
if(null != wakeLock) {
wakeLock.acquire();
}
}
}
// 释放唤醒锁
private void releaseWakeLock() {
if(null != wakeLock) {
wakeLock.release();
wakeLock = null;
}
}
使用WakeLock时,需要切记及时释放锁,有的应用在使用完WakeLock之后会忘记释放它,从而导致屏幕一直显示很长时间,快速的耗费了手机的电量。通常情况下,我们要尽早地释放WakeLock,例如在播放视频时获取WakeLock保持屏幕常亮,在暂停播放时就应该及时地释放锁,而不是等到停止播放才释放,在应用恢复播放时再次获取WakeLock即可。
《Android高级进阶》——顾浩鑫