1.为了省电,有些工作可以当手机插上电源的时候去处理。
像这些不需要及时地和用户交互的操作可以放到后面处理。
比如:360手机助手,当充上电的时候,才去更新App
如何立即获取手机当前充电状态?
//获取手机充电状态
public boolean isPlugged() {
// 通过广播接收者获取
IntentFilter intentFilter = new IntentFilter(
Intent.ACTION_BATTERY_CHANGED);
// 获取Intent。充电情况在intent中
Intent intent = this.registerReceiver(null, intentFilter);
// 获取充电状态。int值。int可以代表很多状态。
int pluggedState = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
// USB充电
boolean usb = pluggedState == BatteryManager.BATTERY_PLUGGED_USB;
// 交流点充电
boolean ac = pluggedState == BatteryManager.BATTERY_PLUGGED_AC;
// 无线充电,当无线充电支持api >= 17
boolean wireless = false;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1) {
wireless = pluggedState == BatteryManager.BATTERY_PLUGGED_WIRELESS;
}
return usb || ac || wireless;
}
2.Wake Lock
在使用该类的时候,必须保证acquire和release是成对出现的。
因为创建和持有唤醒锁对电池的续航有较大的影响。如果不释放WakeLock的话,CPU一直运行,耗电会非常快。
3.集中处理算法,JobSchedule/GCM
CUP唤醒时的高峰线:
image.png从上图可以看出。在唤醒的CPU耗电是相对于唤醒之后要高得多得多。
所以大量高频次的CPU唤醒及操作,我们最好把这些唤醒和操作集中处理。这样有利于优化电量
我们可以采取一些算法来解决。
谷歌提供了Jobschedule(5.0Api)/GCM算法来解决。
JobScheduler示例:
JobService
package com.zsj.jobscheduler;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.HttpURLConnection;
import java.net.URL;
import android.annotation.SuppressLint;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.util.Log;
@SuppressLint("NewApi")
public class MyJobScheduler extends JobService {
private static final String LOG_TAG = "zsjJobScheduler";
@Override
public boolean onStartJob(JobParameters params) {
// 这是您实现所有工作逻辑的地方。 请注意,这运行
// 在主线程上,所以您将要使用单独的线程进行异步工作
// false: 该系统假设任何任务运行不需要很长时间并且到方法返回时已经完成。
// true: 该系统假设任务是需要一些时间并且当任务完成时需要调用jobFinished()告知系统。
// 首先,检查网络,然后尝试连接。
if (isNetworkConnected()) {
new SimpleDownloadTask().execute(params);
return true;
} else {
Log.i(LOG_TAG, "没有网络去工作" + params.getJobId());
}
return false;
}
/**
* 确定设备当前是否在线。
*/
private boolean isNetworkConnected() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
@Override
public boolean onStopJob(JobParameters params) {
// 如果在调用jobFinished()之前必须停止作业,则这个方法。
return false;
}
/**
* 异步任务
*/
private class SimpleDownloadTask extends
AsyncTask<JobParameters, Void, String> {
protected JobParameters mJobParam;
@Override
protected String doInBackground(JobParameters... params) {
mJobParam = params[0];
try {
//做耗时操作
} catch (IOException e) {
return "下载失败";
}
}
@Override
protected void onPostExecute(String result) {
// job 完成。
jobFinished(mJobParam, false);
Log.i(LOG_TAG, "获取结果 : " + result);
}
}
}
调用:
package com.zsj.jobscheduler;
import android.app.Activity;
import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
private ComponentName mJobService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, MyJobScheduler.class));
mJobService = new ComponentName(this, MyJobScheduler.class);
}
public void jobschedule(View view) {
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
for (int i = 0; i < 50; i++) {
int jobId = i;
/*
* new JobInfo.Builder(jobId, mJobService)
* 第一个参数为该任务的标识符
* 第二个参数是你希望用来处理该任务的服务对应的ComponentName,用来启动该服务
*/
JobInfo job = new JobInfo.Builder(jobId, mJobService)
/*
* setBackoffCriteria(initialBackoffMillis, backoffPolicy)//
* 设置退避/重试策略。当一个任务的调度失败时需要重试,所采取的策略。
* 第一个参数时第一次尝试重试的等待间隔,单位为毫秒。预设的参数有:DEFAULT_INITIAL_BACKOFF_MILLIS.,MAX_BACKOFF_DELAY_MILLIS
* 第二个参数是对应的退避策略,预设的参数有:BACKOFF_POLICY_EXPONENTIAL——指数增长退避策略。BACKOFF_POLICY_LINEAR-线性策略
*/
.setBackoffCriteria(JobInfo.DEFAULT_INITIAL_BACKOFF_MILLIS, JobInfo.BACKOFF_POLICY_EXPONENTIAL)
.setMinimumLatency(60)//设置任务执行延迟的时长
// .setPeriodic(long interval)//设置周期。可以保证在每个间隔之间任务最多只执行一次
// .setPeriodic (long interval, long flexMillis) //在周期末的一个flex长度的窗口期(),任务都有可能被执行
// .setPersisted (boolean isPersisted) 设置当设备重启后,这个任务是否还保留。需要RECEIVE_BOOT_COMPLETED权限
/*
* setRequiredNetworkType (int networkType) 设置要求的网络,只有连接给定类型的网络才能执行,常用预设值有:
* NETWORK_TYPE_UNMETERED - 免费网络, NETWORK_TYPE_ANY - 任意网络
*/
// .setRequiresCharging (boolean requiresCharging) 设置是否需要充电CIA执行。默认false
// setRequiresDeviceIdle (boolean requiresDeviceIdle) 设置是否需要设备处于空闲时执行。默认false
.build();//创建对应的JobInfo
jobScheduler.schedule(job);
}
}
}
注册:
<service
android:name="com.zsj.jobscheduler.MyJobScheduler"
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
也可参考谷歌官方Demo:https://github.com/googlesamples/android-JobScheduler
网友评论