社区编辑申请
注册/登录
有效控制Android应用程序的耗电量
移动开发 Android
如何才能降低Android应用程序的耗电量呢?今天再一次回顾了一下09年Google IO大会Jeffrey Sharkey的演讲(Coding for Life — Battery Life, That Is),与大家一起分享有效控制Android软件的耗电问题。

51CTO在对尚邮架构师的访谈中曾经探讨过移动开发是否要重视移动终端软件的耗电问题,答案是显而易见的!那么如何才能降低Android应用程序的耗电量呢?今天再一次回顾了一下09年Google IO大会Jeffrey Sharkey的演讲(Coding for Life — Battery Life, That Is),同时也讲一下应该如何有效地控制耗电量问题。

首先我们来看看Android手机的电量都主要消耗在了什么地方:

显而易见,大部分的电都消耗在了网络连接、GPS、传感器上了。

简单的说也就是主要在以下情况下耗电比较多:

1、 大数据量的传输。

2、 不停的在网络间切换。

3、 解析大量的文本数据。

那么我们怎么样来改善一下我们的程序呢?

1、 在需要网络连接的程序中,首先检查网络连接是否正常,如果没有网络连接,那么就不需要执行相应的程序。

检查网络连接的方法如下:

  1.  
  2. ConnectivityManager mConnectivity;  
  3.  
  4. TelephonyManager mTelephony;  
  5.  
  6.  ……  
  7.  
  8. // 检查网络连接,如果无网络可用,就不需要进行连网操作等  
  9.  
  10. NetworkInfo info = mConnectivity.getActiveNetworkInfo();  
  11.  
  12. if (info == null ||  
  13.  
  14.         !mConnectivity.getBackgroundDataSetting()) {  
  15.  
  16.         return false;  
  17.  
  18. }  
  19.  
  20. //判断网络连接类型,只有在3G或wifi里进行一些数据更新。  
  21.  
  22. int netType = info.getType();  
  23.  
  24. int netSubtype = info.getSubtype();  
  25.  
  26. if (netType == ConnectivityManager.TYPE_WIFI) {  
  27.  
  28.     return info.isConnected();  
  29.  
  30. } else if (netType == ConnectivityManager.TYPE_MOBILE  
  31.  
  32.         && netSubtype == TelephonyManager.NETWORK_TYPE_UMTS  
  33.  
  34.         && !mTelephony.isNetworkRoaming()) {  
  35.  
  36.     return info.isConnected();  
  37.  
  38. } else {  
  39.  
  40.     return false;  
  41.  
  42. }  
  43.  

 2、 使用效率高的数据格式和解析方法。

通过测试发现,目前主流的数据格式,使用树形解析(如DOM)和流的方式解析(SAX)对比情况如下图所示:

很明显,使用流的方式解析效率要高一些,因为DOM解析是在对整个文档读取完后,再根据节点层次等再组织起来。而流的方式是边读取数据边解析,数据读取完后,解析也就完毕了。

在数据格式方面,JSON和Protobuf效率明显比XML好很多,XML和JSON大家都很熟悉,Protobuf是Google提出的,一种语言无关、平台无关、扩展性好的用于通信协议、数据存储的结构化数据串行化方法。有兴趣的可以到官方去看看更多的信息

从上面的图中我们可以得出结论就是尽量使用SAX等边读取边解析的方式来解析数据,针对移动设备,最好能使用JSON之类的轻量级数据格式为佳。

3、 目前大部门网站都支持GZIP压缩,所以在进行大数据量下载时,尽量使用GZIP方式下载。

使用方法如下所示:

  1.  
  2. import java.util.zip.GZIPInputStream;  
  3.  
  4. HttpGet request =  
  5.  
  6.     new HttpGet("http://example.com/gzipcontent");  
  7.  
  8. HttpResponse resp =  
  9.  
  10.     new DefaultHttpClient().execute(request);  
  11.  
  12. HttpEntity entity = response.getEntity();  
  13.  
  14. InputStream compressed = entity.getContent();  
  15.  
  16. InputStream rawData = new GZIPInputStream(compressed);  
  17.  

使用GZIP压缩方式下载数据,能减少网络流量,下图为使用GZIP方式获取包含1800个主题的RSS对比情况。

4、 其它一些优化方法:

回收java对象,特别是较大的java对像

  1. XmlPullParserFactory and BitmapFactory   
  2.  
  3. Matcher.reset(newString) for regex  
  4.  
  5. StringBuilder.sentLength(0)  
  6.  

对定位要求不是太高的话尽量不要使用GPS定位,可能使用wifi和移动网络cell定位即可。GPS定位消耗的电量远远高于移动网络定位。

尽量不要使用浮点运算。

获取屏幕尺寸等信息可以使用缓存技术,不需要进行多次请求。

很多人开发的程序后台都会一个service不停的去服务器上更新数据,在不更新数据的时候就让它sleep,这种方式是非常耗电的,通常情况下,我们可以使用AlarmManager来定时启动服务。如下所示,第30分钟执行一次。

  1. AlarmManager am = (AlarmManager)  
  2.  
  3.         context.getSystemService(Context.ALARM_SERVICE);  
  4.  
  5. Intent intent = new Intent(context, MyService.class);  
  6.  
  7. PendingIntent pendingIntent =  
  8.  
  9.         PendingIntent.getService(context, 0, intent, 0);  
  10.  
  11. long interval = DateUtils.MINUTE_IN_MILLIS * 30;  
  12.  
  13. long firstWake = System.currentTimeMillis() + interval;  
  14.  
  15. am.setRepeating(AlarmManager.RTC,firstWake, interval, pendingIntent);  
  16.  

最后一招,在运行你的程序前先检查电量,电量太低,那么就提示用户充电之类的,使用方法:

  1.  
  2. public void onCreate() {  
  3.  
  4.     // Register for sticky broadcast and send default  
  5.  
  6.     registerReceiver(mReceiver, mFilter);  
  7.  
  8.     mHandler.sendEmptyMessageDelayed(MSG_BATT, 1000);  
  9.  
  10. }  
  11.  
  12. IntentFilter mFilter =  
  13.  
  14.         new IntentFilter(Intent.ACTION_BATTERY_CHANGED);  
  15.  
  16. BroadcastReceiver mReceiver = new BroadcastReceiver() {  
  17.  
  18.     public void onReceive(Context context, Intent intent) {  
  19.  
  20.         // Found sticky broadcast, so trigger update  
  21.  
  22.         unregisterReceiver(mReceiver);  
  23.  
  24.         mHandler.removeMessages(MSG_BATT);  
  25.  
  26.         mHandler.obtainMessage(MSG_BATT, intent).sendToTarget();  
  27.  
  28.     }  
  29.  
  30. };  

想了解更多内容,请直接查看Google IO 2009相关文档

了解Android开发更多内容请看

Android开发专题

【编辑推荐】

  1. Android创始人:这世界不需要Windows Phone 7
  2. Android数据库事务浅析
  3. 多图详解Android应用程序提交发布全过程
  4. Android的UI设计与后台线程交互
责任编辑:佚名 来源: ideasandroid
相关推荐

2022-05-09 15:08:56

存储厂商NFV领域华为

2022-05-06 09:40:48

智能云原生云原生人工智能

2022-04-15 08:00:00

FUSE开发Android

2022-05-18 23:42:08

网络安全安全分析工具

2022-05-11 14:05:11

区块链网络安全存储

2022-05-13 10:24:44

WineWindowsLinux

2022-05-16 09:40:00

神经网络工具

2022-04-19 08:29:12

Python机器学习

2022-05-16 15:35:00

漏洞黑客

2022-04-12 09:48:22

云计算安全云服务云安全

2022-05-09 11:57:39

云原生实践安全

2022-05-18 08:05:31

2022-04-19 14:41:29

Oracle数据库SQL

2022-05-10 16:04:40

编程语言PythonC语言

2022-05-07 15:31:19

物联网5G智慧城市

2022-05-17 09:19:17

XebianLinuxLinux 发行版

2022-05-07 09:08:13

路由策略网络规划

2022-05-10 14:11:55

人工智能金融科技机器学习

2022-05-06 16:31:27

人工智能自然语言生物特征识别

2022-04-30 08:43:52

Spring模块化框架

同话题下的热门内容

携程机票跨端跨框架 UI 自动化测试方案 Flybirds携程基于BookKeeper的延迟消息架构落地实践西瓜视频 iOS Voice Over 无障碍适配实践快速提升 UI 设计效果的六个小技巧苹果发布 iOS 15.5 正式版:更流畅、支持部分应用第三方支付苹果官宣:iOS 16 有这些强大新功能iOS16被传Bug太多,大家最好晚点更新iOS 16 来了,苹果新系统曝光

编辑推荐

2017年9月编程语言排行榜:Java、C与C++三巨头还能统治排行榜多久?初学者最容易学的六种编程语言CVPR 2017论文解读:特征金字塔网络FPN手把手教你搭建PHP版RabbitMQ消息队列开发环境及Demo实践微信小程序“反编译”实战(一):解包
我收藏的内容
点赞
收藏

51CTO技术栈公众号