电量测试
电量测试:就是测试移动设备电量消耗快慢的一种测试方法。一般用平均电流来衡量电量消耗速度。平均电流越小,说明设备使用时间越长。但是平均电流多大才说明不耗电却没有一个统一标准。
硬件测试:利用硬件设备测试被测设备的电流,统计一段时间内(使用某个功能模块)的平均电流值。
软件测试:利用系统工具导出分析报告
我们进行电量测试的时候,一般都是用软件测试的一种方式.
安装流程有点复杂,就不在这里说了,这里主要是做代码分析,如果需要安装流程也可以私聊我
WakeLock
其实很多公司项目里面都适用WeakLock,这种方式并不一定好,对CPU的性能消耗比较大。
电量优化(JobScheduler)
以高德地图的Demo为例子,坐标是实实变化的,无时无刻不在上传到服务器,其实这种方法是非常耗电的。
对于及时性挺高的功能,也可以使用闹钟。但是最好的办法就是使用 JobScheduler,它可以把一些不是特别紧急的任务放到更合适的时机批量处理。避免频繁的唤醒硬件模块,避免在不合适的时候执行一些耗时任务。我不可能每次接收到一个坐标就把一个坐标发送到服务器,这样发送没有必要。我们可以一次性整合到单次发送。JobScheduler是一个系统服务。以下是核心代码:仅仅是在充电情况下和wifi情况下才会执行这个服务。具体根据业务来
public class JobManager {
static JobManager instance;
//把一些不是特别紧急(实时)的任务放到更合适的时机批量处理
// 1、避免频繁的唤醒硬件模块
// 2、避免在不合适的时候执行一些耗电的任务
private JobScheduler jobScheduler;
private Context context;
private static final int jobId=0;
public static JobManager getInstance() {
if (null == instance)
instance = new JobManager();
return instance;
}
public void init(Context context) {
this.context = context.getApplicationContext();
jobScheduler = (JobScheduler)
context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
}
/**
* 添加一个任务
* @param location
*/
public void addJob(String location) {
if (null == jobScheduler) {
return;
}
JobInfo pendingJob = null;
//整合多个job
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//查找id是0的job
pendingJob = jobScheduler.getPendingJob(jobId);
} else {
List<JobInfo> allPendingJobs = jobScheduler.getAllPendingJobs();
for (JobInfo info : allPendingJobs) {
if (info.getId() == jobId) {
pendingJob = info;
break;
}
}
}
//找到待执行的job
if (null != pendingJob) {
//多个坐标信息拼到一起 上传
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//数据 与Intent 一样
PersistableBundle extras = pendingJob.getExtras();
//获得上一次设置的location数据
String data = extras.getString("DATA");
//比如 多条坐标数据用@隔开
location = data + "@" + location;
jobScheduler.cancel(jobId);
}
}
// jobid :0
PersistableBundle extras = new PersistableBundle();
extras.putString("DATA",location);
//创建一个job
JobInfo jobInfo = new
JobInfo.Builder(jobId,
new ComponentName(context, MyJobService.class))
//只在充电的时候
.setRequiresCharging(true)
//不是蜂窝网络
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setExtras(extras).build();
//提交任务
jobScheduler.schedule(jobInfo);
}
}
public class MyJobService extends JobService {
public static final String TAG = "MyJobService";
@Override
public boolean onStartJob(JobParameters params) {
//如果返回值是false,这个方法返回时任务已经执行完毕。
//如果返回值是true,那么这个任务正要被执行,我们就需要开始执行任务。
//当任务执行完毕时你需要调用jobFinished(JobParameters params, boolean needsRescheduled)来通知系统
new MyAsyncTask().execute(params);
return true;
}
//当系统接收到一个取消请求时
@Override
public boolean onStopJob(JobParameters params) {
//如果onStartJob返回false,那么onStopJob不会被调用
// 返回 true 则会重新计划这个job
return false;
}
/**
* Params:启动任务时输入的参数类型.
* <p>
* Progress:后台任务执行中返回进度值的类型.
* <p>
* Result:后台任务执行完成后返回结果的类型.
*/
class MyAsyncTask extends AsyncTask<JobParameters, Void, Void> {
JobParameters jobParameters;
@Override
protected Void doInBackground(JobParameters[] objects) {
jobParameters = objects[0];
Log.i(TAG, jobParameters.getJobId() + " 任务开始执行......");
PersistableBundle extras = jobParameters.getExtras();
String location = extras.getString("DATA");
Log.i(TAG, jobParameters.getJobId() + " 上传:" + location);
HttpURLConnection conn = null;
OutputStream os = null;
try {
conn = (HttpURLConnection) new URL("https://www.baidu.com/")
.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
os = conn.getOutputStream();
os.write(location.getBytes());
os.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
Utils.safeColose(os);
if (null != conn) {
conn.disconnect();
}
}
return null;
}
/**
* doInBackground:必须重写,异步执行后台线程要完成的任务,耗时操作将在此方法中完成.
* <p>
* onPreExecute:执行后台耗时操作前被调用,通常用于进行初始化操作.
* <p>
* onPostExecute:当doInBackground方法完成后,系统将自动调用此方法,并将doInBackground方法返回的值传入此方法.通过此方法进行UI的更新.
* <p>
* onProgressUpdate:当在doInBackground方法中调用publishProgress方法更新任务执行进度后,将调用此方法.通过此方法我们可以知晓任务的完成进度.
*/
@Override
protected void onPostExecute(Void s) {
//当任务执行完毕之后,需要调用jobFinished来让系统知道这个任务已经结束,
//系统可以将下一个任务添加到队列中
//true表示需要重复执行
//false反之
jobFinished(jobParameters, false);
Log.i(TAG, j obParameters.getJobId() + "任务执行完成......");
}
}
}
记得在AndroidMainifest注册这个MyJobService
<service
android:name=".MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:process=":location" />
在Application里面调用
applicationt = this;
location = new Intent(this, LocationService.class);
startService(location);
public class LocationService extends Service {
// private PowerManager.WakeLock locationLock;
/*private Intent alarmIntent;*/
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
JobManager.getInstance().init(this);
LocationManager.getInstance().startLocation(this);
//使用WeakLock
// PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
//判断是否支持
// pm.isWakeLockLevelSupported(PowerManager.PARTIAL_WAKE_LOCK);
//只唤醒cpu
// locationLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
// "location_lock");
// locationLock.acquire();
/* alarmKeep();*/
}
@Override
public void onDestroy() {
super.onDestroy();
//释放
LocationManager.getInstance().destoryLocation();
//注销广播接收者
/* unregisterReceiver(alarmReceiver);
// if (null != locationLock) {
// locationLock.release();
// }*/
}
/* private void alarmKeep() {
alarmIntent = new Intent();
alarmIntent.setAction("LOCATION");
//创建延迟意图
PendingIntent broadcast = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
//获得闹钟管理器
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
//动态注册广播接受者
IntentFilter filter = new IntentFilter();
filter.addAction("LOCATION");
registerReceiver(alarmReceiver,filter);
//设置一个 每隔 5s 发送一个广播
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,SystemClock.elapsedRealtime(),
5_000,broadcast);
}*/
/*BroadcastReceiver alarmReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (TextUtils.equals(intent.getAction(),"LOCATION")){
LocationManager.getInstance().startLocation(LocationService.this);
}
}
};*/
}
初始化只是换了一种方式而已
然后在高德地图API里面换一种写发,注意对应服务器地址,这里是随便写了一下
image.png image.png
网友评论