如何编写更省电的Android应用

为什么要省电?


电池的容量没有大幅度的提升,使用Android手机会越来越耗电,电池的可用时间极大的缩短。

有哪些地方在耗电?

1. 网络、GPS、传感器和CPU等

2. 不合理的使用屏幕唤醒wakelock

3. 后台应用过多,频繁进行数据更新操作

4. 不合理的设置屏幕亮度值和屏幕超时值等

5. 启动多个service6. 创建大量的临时对象

怎样编写更省电?

只在WiFi或3G下使用网络

// 只在WiFi或3G下使用网络
 NetworkInfo info;
 int netType = info.getType();
 int netSubtype = info.getSubtype();
 if (netType == ConnectivityManager.TYPE_WIFI) {

 return info.isConnected();

 } else if (netType == ConnectivityManager.TYPE_MOBILE
 && netSubtype == TelephonyManager.NETWORK_TYPE_UMTS
 && !mTelephony.isNetworkRoaming()) {

 return info.isConnected();

 } else {
 return false;
 }

设置网络连接超时

设置网络连接超时时间
正确
URL httpUrl = new URL(url);
HttpURLConnection connection =
(HttpURLConnection)httpUrl.openConnection();
connection.setConnectTimeout(5000) // unit milliseconds
错误
URL httpUrl = new URL(url);
HttpURLConnection connection =
(HttpURLConnection)httpUrl.openConnection();
//connection.setConnectTimeout(timeout) //default 0s

尽量使用GZIP进行文本数据的传输

尽量使用GZIP进行文本数据传输
import java.util.zip.GZIPInputStream;
HttpGet request = new  
HttpGet("http://example.com/gzipcontent");
HttpResponse resp = new
DefaultHttpClient().execute(request);
HttpEntity entity = response.getEntity();
InputStream compressed = entity.getContent();
InputStream rawData = new
GZIPInputStream(compressed); 

缓存文件到本地

缓存文件到本地
HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(
CoreConnectionPNames.SO_TIMEOUT, 5000);
HttpGet httpget = new HttpGet("http://example.com/
pictures");
HttpResponse response = httpclient.execute(httpget);
Header[] header = response.getHeaders("ETag");
if(header != null && header.length > 0){
String catch = header[0].toString();
}

减少连接次数

重用已经存在的网络连接比新建立一个连接通常更有效率的由于http协议的“三次握手”

判断GPS开关状态

判断GPS开关状态
正确
String provider = Settings.Secure.getString(
context.getContentResolver(),Settings.Secure.LOCATION_PROVIDE
RS_ALLOWED);
if (provider != null && provider.contains("gps")) {
 return true;
}
错误
LocationManager lManager = (LocationManager)
context.getSystemService(Context.LOCATION_SERVICE);
lManager .isProviderEnabled(LocationManager.GPS_PROVIDER); 
Sensor
Sensor
正确
 @Override
protected void onResume() {
mSensorManager.registerListener(this,mSensorManager.getDefaultS
ensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR
_DELAY_NORMAL);
}
@Override
protected void onPause() {
mSensorManager.unregisterListener(this);
}
Sensor
错误
public final class BkService extends Service implements
SensorEventListener{
 @Override
protected void onStart() {
mSensorManager.registerListener(this,mSensorManager.getDefaultS
ensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR
_DELAY_NORMAL);
}
@Override
protected void onDestroy() {
mSensorManager.unregisterListener(this); 
}

调整定时更新的频率

调整定时更新的频率
int alarmType = AlarmManager.ELAPSED_REALTIME;
long interval = AlarmManager.INTERVAL_HOUR;
long start = System.currentTimeMillis() + interval;
alarmManager.setInexactRepeating(alarmType, start,
interval, pi);
如果可以,请设置提醒的类型为ELAPSED_REALTIME or RTC
而不是_WAKEUP。这样在系统睡眠的时候不会唤醒CPU。

回收Java对象

回收java对象
有些对象的回收不能依赖于JAVA的GC
XmlPullParserFactory and BitmapFactory
Matcher.reset(newString) for regex
StringBuilder.setLength(0) 

使用软引用

使用软引用
正确
ApplicationInfo ai;
PackageManager mPm;
ai = mPm.getApplicationInfo(app.pkgName, 0);
app.icon = new SoftReference<Drawable>(ai.loadIcon(mPm));
holder.iconView.setImageDrawable(app.icon.get());
错误
ai = mPm.getApplicationInfo(app.pkgName, 0);
Drawable icon= ai.loadIcon(mPm);
holder.iconView.setImageDrawable(icon); 

按需操控广播接受者

按需操控广播接收者
ComponentName receiver = new ComponentName(context,
myReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_EN
ABLED, PackageManager.DONT_KILL_APP) 

数据库使用事务

数据库使用事务
SQLiteDatabase db = mHelper.getWritableDatabase();
db.beginTransaction();
try{
 for (int i = 0; i < usageHisList.size(); i++) {
 db.insert(table,null, values);
}
db.setTransactionSuccessful();
}catch(Exception ex){
}
db.endTransaction(); 

动画

正确
@Override
protected void onResume() {
image.startAnimation(mChargingAnim); //开始动画
}
@Override
protected void onPause() {
image.clearAnimation(); //结束动画
}
<pre name="code" class="java">错误
@Override
protected void onCreate(Bundle b) {
image.startAnimation(mChargingAnim); //开始动画
}
@Override
protected void onDestory() {
image.clearAnimation(); //结束动画
}

 

尽量使用Application Context

尽量使用 application context
在android中有两种context,一种是 application context,一种是activity context。
public class BatteryActivity extends Activity {
 private static Drawable mBackground;
 protected void onCreate(Bundle state) {
 super.onCreate(state);
 TextView label = new TextView(this.getApplicationContext());
 label.setText("It is good !");
 if (mBackground == null) {
 mBackground = getDrawable(R.drawable.battery_info);
 }
 label.setBackgroundDrawable(mBackground);//drawable attached to a view
 setContentView(label);
 }
} 

尽量减少布局层次

尽量减少布局层次
1. Textview +Imageview → Textview
+icon(android:drawableXXX)
2. 多个LinearLayout→单个RelativeLayout
3. 通过<include /> 标签来重用layout代码
4. 使用<merge /> 标签来减少视图层级结构


性能分析工具介绍

tools/hierarchyviewer.bat查看UI布局设计结构和各种属性的信息

tools/lint.bat分析布局文件合理性,给出优化建议

tools/traceview.bat查看函数以及子函数运行时间

tools/systrace/systrace.py可以从Linux内核中直接收集数据,来帮助诊断性能问题

转载链接:http://os.51cto.com/exp/velocity2012/ppt/hantao.pdf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值