uc欣赏 器下载的文件怎么导出_uc欣赏 器官网网址导航(uc看好东西)
电量斲丧 的盘算 与统计是一件贫苦 而且抵牾 的事变 ,记录 电量斲丧 本身 也是一个费电量的事变 ,随着Android的性能要求越来越高,电量的优化,也显得格外紧张 ,一个耗电的应用,用户肯定会绝不 夷由 的举行 卸载,以是 本篇博客,我们一起来学习Android性能优化之电量优化。
耗电是怎样 产生的?
耗电环境 ,比方 :打开屏幕,全部 要利用 CPU/GPU工作的动作都会唤醒 屏幕,都会斲丧 电量。这和应用程序唤醒 装备 还不一样。
(1)唤醒 屏幕
当用户电量屏幕的时间 ,意味着体系 的各组件要开始举行 工作,界面也必要 开始实行 渲染。
待机状态的电量斲丧 :
利用 和唤醒 屏幕后:
当装备 从休眠状态中,被应用程序唤醒 时,就会产生一条电量利用 高峰线。
当工作完成后,装备 会主动 举行 休眠,这非常紧张 ,在不利用 大概 很少利用 的环境 下,长时间保持屏幕唤醒 会敏捷 斲丧 电池的电量。
(2)蜂窝式无线
通过这张图,我们知道通过利用 蜂窝无线时,会产生几个高峰:
当装备 通过无线网发送数据的时间 ,为了利用 硬件,这里会出现一个唤醒 好点高峰。
接下来尚有 一个高数值,这是发送数据包斲丧 的电量,
然后担当 数据包也会斲丧 大量电量 也看到一个峰值。
开启无线模式这个过程非常耗电,那么硬件这块为了防止频仍 开启关闭耗电,采取 了一个无奈的办法,会在一个小段时间内保持开启模式,防止短时间内尚有 数据包必要 吸取 ,也就是图中的Keep Awake的那一段。
怎样 举行 电量利用 分析?
(1)电量数据网络
Android 5.0及以上的装备 , 答应 我们通过adb下令 dump出电量利用 统计信息.
1.由于 电量统计数据是连续 的, 统计我们的待测试App之前先reset下, 连上装备 , 下令 行实行 :
$ adb shell dumpsys batterystats --reset
Battery stats reset.
2.断开测试装备 , 操纵 我们的待测试App.
3.重新毗连 装备 , 利用 adb下令 导出相干 统计数据:
// 此下令 连续 记录 输出, 想要克制 记录 时按Ctrl+C退出.
$ adb bugreport bugreport.txt
导出的统计数据存储到bugreport.txt, 此时我们可以借助如下工具来图形化展示电池的斲丧 环境 .
留意 , 官方SDK文档导出文件方式为:
adb shell dumpsys batterystats batterystats.txt
利用 Python historian.py batterystats.txt batterystats.html查察 数据
是battery-historian老版本的利用 方式. 如今 Battery Historian已更新2.0版本, 保举 利用 bugreport方式导出数据分析, 可以看到更多信息.
(2)电量分析工具Battery Historian
工具开源地点 : https://github.com/google/battery-historian
根据gitbub上面先容 ,Battery History工具的安装有两种方式:
1.通过安装Docker环境 来安装。(必要 翻墙)
Docker只支持Windows10
Gitbub上面是如许 的下令 及地点 :
docker -- run -p port:9999 gcr.io/android-battery-historian:2.1 --port 9999
2.通过编译gitbub上面的源码来安装。
(1)GO环境 安装:
1.下载
下载目次 :https://golang.org/doc/install
https://golang.org/doc/install?download=go1.7.3.windows-amd64.msi
2.安装GO
3.设置 GOROOT和GOPATH
a. GOROOT的作用是告诉Go 下令 和其他相干 工具,在那边 去找到安装在你体系 上的Go包,以是 这里设置 的是GO的安装目次
b.GOPATH可以简单 明白 为是工程的目次 ,以是 创建一个GO的工程路径
C.末了 设置 一下环境 变量,把Go的bin目次 放到path环境 变量中
D. 查抄 Go是否安装乐成 ,打开下令 行输入Go version
(2)安装Git
2.按照步调 安装;
3.安装完成查抄 :下令 行输入git version
(3)安装Python
2.安装完成;
3.环境 变量设置 ,添加Path的路径,是Python的安装路径
4.输入下令 行 python –V(留意 是大写V)查抄 是否安装乐成
(4)安装Java环境
1.点击下载:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html;
2.完成安装。
(5)下载Battery Historian源码而且 运行
输入下令 行go get -d -u github.com/google/battery-historian/...
下载到GOPATH设置 目次 下
1.进入到$GOPATH/src/github.com/google/battery-historian目次 下方
$ cd $GOPATH/src/github.com/google/battery-historian
2.运行Battery Historian
1) go run setup.go
$ go run setup.go
等待 数分钟大概 10分钟左右,假如 仍旧 没有下载乐成 ,可以手动下载,如下操纵
下载【closure-library】和【closure-compiler】和【flot-axislabels】,解压放到GOROOT目次 下third_party文件夹下方的的closure-compiler和closure-library和flot-axislabels文件夹 ../battery-historianhird_party;假如 没有均手动创建
2)go run cmd/battery-historian/battery-historian.go
$ go run cmd/battery-historian/battery-historian.go [--port default:9999]
battery-historian利用
数据预备
battery-historian工具必要 利用 bugreport中的Battery History
1.先断开adb服务,然后开启adb服务
adb kill-server 这一步很紧张 ,由于 当我们开辟 时做电量记录 时会打开很多 大概 造成辩论 的东西。为了保险起见我们重启adb。
adb devices就会主动 毗连 查找手机。固然 也可以adb start-server
2.重置电池数据网络
数据,我们在开始的时间 必要 通过以下下令 来打开电池数据的获取以及重置:
adb shell dumpsys batterystats --enable full-wake-history
adb shell dumpsys batterystats --reset
上面的操纵 相称 于初始化操纵 ,假如 不这么做会有一大堆的干扰的数据,看起来会比力 痛楚 。然后把数据线直接拔掉(防止数据线造成充放电数据干扰),如今 做一些测试,手动大概 跑一些主动 化的case都行。颠末 一段时间后,我们重新毗连 办 机确认adb连上了,运行下面这条下令 来将bugreport的信息生存 到txt文档中,
adb bugreport bugreport.txt
大概 用下面的下令 也可以:
adb shell dumpsys batterystats batterystats.txt
adb shell dumpsys batterystats com.example.android.demo.app batterystats.txt
加上包名可以限定 输出的数据是我们要检测的。
但是这个txt的数据可读性不强。接下来我们就要用到这个battery-historian工具了。
分析数据
各个参数的意义
起首 我们在bugreport.txt找到Battery History数据栏雷同 下面的信息:
DUMP OF SERVICE batterystats:
Battery History (2% used, 5980 used of 256KB, 45 strings using 2592):
0 (9) RESET:TIME: 2015-03-05-15-21-56
0 (2) 100 c0900422 status=discharging health=good plug=none temp=200 volt=4167 +running +wake_lock +sensor +screen data_conn=edge phone_signal_strength=great brightness=medium proc=u0a15:"android.process.acore"
0 (2) 100 c0900422 proc=u0a7:"com.android.cellbroadcastreceiver"
0 (2) 100 c0900422 proc=u0a53:"com.android.gallery3d"
你在html中信息都能从bugreport.txt中找到相应的信息。
如今 来分析各个指标代表的意义:
横坐标
上面的10,20代表的就是秒的意思,它是以一分钟为周期,到第60秒的时间 变为0。横坐标就是一个时间范围,咱们的例子中统计的数据是以重置为出发点 ,获取bugreport内容时候 为尽头 。我们一共收罗 了多长时间的数据,图表下也有信息阐明 。(经其他人的反馈,这个坐标隔断 是会随着时间的长度发生改变,以是 要以你的实际 环境 为准。这个缩放级别可以调解 的,如下图:)
纵坐标
举行 电量优化
Track Battery Status Battery Manager
我们可以通过下面的代码来获取手机的当前充电状态:
// It is very easy to subscribe to changes to the battery state, but you can get the current
// state by simply passing null in as your receiver. Nifty, isn't that?
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = this.registerReceiver(null, filter);
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
boolean acCharge = (chargePlug == BatteryManager.BATTERY_PLUGGED_AC);
if (acCharge) {
Log.v(LOG_TAG,“The phone is charging!”);
}
在上面的例子演示了怎样 立即 获取得手 机的充电状态,得到充电状态信息之后,我们可以有针对性的对部分 代码做优化。比如 我们可以判定 只有当前手机为AC充电状态时 才去实行 一些非常耗电的操纵 。
/** * This method checks for power by comparing the current battery state against all possible * plugged in states. In this case, a device may be considered plugged in either by USB, AC, or * wireless charge. (Wireless charge was introduced in API Level 17.) */
private boolean checkForPower() {
IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); Intent batteryStatus = this.registerReceiver(null, filter);
// There are currently three ways a device can be plugged in. We should check them all.
boolean usbCharge = (chargePlug == BatteryManager.BATTERY_PLUGGED_USB);
boolean acCharge = (chargePlug == BatteryManager.BATTERY_PLUGGED_AC);
boolean wirelessCharge = false;
if (Build.VERSION.SDK_INT = Build.VERSION_CODES.JELLY_BEAN_MR1)
{ wirelessCharge = (chargePlug == BatteryManager.BATTERY_PLUGGED_WIRELESS);
}
return (usbCharge || acCharge || wirelessCharge);
}
屏幕唤醒
有些时间 我们必要 改变Android体系 默认的这种状态:比如 玩游戏时我们必要 保持屏幕常亮,比如 一些下载操纵 不必要 屏幕常亮但必要 CPU不停 运行直到任务 完成。
最好的方式是在Activity中利用 FLAG_KEEP_SCREEN_ON 的Flag。
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
另一个方式是在布局 文件中利用 android:keepScreenOn属性:
RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
...
/RelativeLayout
android:keepScreenOn = ” true “的作用和FLAG_KEEP_SCREEN_ON一样。利用 代码的长处 是你答应 你在必要 的地方关闭屏幕。
留意 :一样平常 不必要 人为的去掉FLAG_KEEP_SCREEN_ON的flag,windowManager会管理好程序进入背景 回到前台的的操纵 。假如 确实必要 手动清掉常亮的flag,利用 getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
Wakelock and Battery Drain
假设你的手机内里 装了大量的交际 类应用,纵然 手机处于待机状态,也会常常 被这些应用唤醒 用来查抄 同步新的数据信息。一个最简单 的唤醒 手机的方法是利用 PowerManager.WakeLock的API来保持CPU工作并防止屏幕变暗关闭。这使得手机可以被唤醒 ,实行 工作,然后回到就寝 状态。知道怎样 获取WakeLock是简单 的,但是 及时 开释 WakeLock也黑白 常紧张 的,不得当 的利用 WakeLock会导致严峻 错误。比方 网络哀求 的数据返回时间不确定,导致原来 只必要 10s的事变 不停 等待 了1个小时,如许 会使得电量白白浪费了。这也是为何利用 带超时参数的wakelock.acquice()方法是很关键的。
wake_lock锁重要 是相对体系 的休眠而言的,意思就是我的程序给CPU加了这个锁那体系 就不会休眠了,如许 做的目标 是为了尽力 共同 我们程序的运行。有的环境 假如 不这么做就会出现一些题目 ,比如 微信等及时 通讯的心跳包会在熄屏不久后克制 网络访问等题目 。以是 微信内里 是有大量利用 到了wake_lock锁。
wake_lock:两种锁,一种计数锁;非计数锁(锁了很多 次,只必要 release一次就可以打扫 了)
唤醒 锁可分别 为并辨认 四种用户唤醒 锁:
自 API 品级 17 开始,FULL_WAKE_LOCK 被弃用。 改为利用 FLAG_KEEP_SCREEN_ON。
添加唤醒 锁权限:
uses-permission android:name="android.permission.WAKE_LOCK" /
直接利用 唤醒 锁:
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,"MyWakelockTag");
wakeLock.acquire();
留意 :在利用 该类的时间 ,必须包管 acquire和release是成对出现的。否则 当我们业务已经不必要 时,当CPU处于唤醒 状态,这个时间 就会斲丧 多余的电量。
但是仅仅设置超时并不敷 够办理 题目 ,比方 设置多长的超时比力 符合 ?什么时间 举行 重试等等?办理 上面的题目 ,精确 的方式大概 是利用 非精准定时器。通常环境 下,我们会设定一个时间举行 某个操纵 ,但是动态修改这个时间大概 会更好。比方 ,假如 有别的 一个程序必要 比你设定的时间晚5分钟唤醒 ,最好可以或许 比及 谁人 时间 ,两个任务 捆绑一起同时举行 ,这就黑白 正确 定时器的核心 工作原理。我们可以定制筹划 的任务 ,但是 体系 假如 检测到一个更好的时间,它可以推迟你的任务 ,以节流 电量斲丧 。
JobScheduler
JobSchedule的宗旨就是把一些不是特别 告急 的任务 放到更符合 的机遇 批量处理 惩罚 。
自界说 一个Service类,继承 自JobService
public class JobSchedulerService extends JobService{
private String TAG = JobSchedulerService.class.getSimpleName();
@Override
public boolean onStartJob(JobParameters jobParameters) {
Log.d(TAG, "onStartJob:" + jobParameters.getJobId());
if(true) {
// JobService在主线程运行,假如 我们这里必要 处理 惩罚 比力 耗时的业务逻辑需单独开启一条子线程来处理 惩罚 并返回true,
// 当给定的任务 完成时通过调用jobFinished(JobParameters params, boolean needsRescheduled)告知体系 。
//假设开启一个线程去下载文件
new DownloadTask().execute(jobParameters);
return true;
}else {
//假如 只是在本方法内实行 一些简单 的逻辑话返回false就可以了
return false;
}
}
/**
* 比如 我们的服务设定的束缚 条件为在WIFI状态下运行,结果 在任务 运行的过程中WIFI断开了体系
* 就会通过回掉onStopJob()来关照 我们克制 运行,正常的环境 下不会回掉此方法
*
* @param jobParameters
* @return
*/
@Override
public boolean onStopJob(JobParameters jobParameters) {
Log.d(TAG, "onStopJob:" + jobParameters.getJobId());
//假如 必要 服务在设定的约定条件再次满意 时再次实行 服务请返回true,反之false
return true;
}
class DownloadTask extends AsyncTaskJobParameters, Object, Object {
JobParameters mJobParameters;
@Override
protected Object doInBackground(JobParameters... jobParameterses) {
mJobParameters = jobParameterses[0];
//比如 说我们这里处理 惩罚 一个下载任务
//或是处理 惩罚 一些比力 复杂的运算逻辑
//...
try {
Thread.sleep(30*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
//假如 在onStartJob()中返回true的话,处理 惩罚 完成逻辑后肯定 要实行 jobFinished()告知体系 已完成,
//假如 必要 重新安排服务请true,反之false
jobFinished(mJobParameters, false);
}
}
}
记得在Manifest文件内设置 Service
service android:name=".JobSchedulerService" android:permission="android.permission.BIND_JOB_SERVICE"/
创建工作筹划
public class MainActivity extends Activity{
private JobScheduler mJobScheduler;
private final int JOB_ID = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mai_layout);
mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE );
//通过JobInfo.Builder来设定触发服务的束缚 条件,最少设定一个条件
JobInfo.Builder jobBuilder = new JobInfo.Builder(JOB_ID, new ComponentName(this, JobSchedulerService.class));
//循环触发,设置任务 每三秒定期运行一次
jobBuilder.setPeriodic(3000);
//单次定时触发,设置为三秒以后去触发。这是与setPeriodic(long time)不兼容的,
// 而且 假如 同时利用 这两个函数将会导致抛出非常 。
jobBuilder.setMinimumLatency(3000);
//在约定的时间内设置的条件都没有被触发时三秒以后开始触发。雷同 于setMinimumLatency(long time),
// 这个函数是与 setPeriodic(long time) 相互 倾轧 的,而且 假如 同时利用 这两个函数,将会导致抛出非常 。
jobBuilder.setOverrideDeadline(3000);
//在装备 重新启动后设置的触发条件是否尚有 效
jobBuilder.setPersisted(false);
// 只有在装备 处于一种特定的网络状态时,它才触发。
// JobInfo.NETWORK_TYPE_NONE,无论是否有网络均可触发,这个是默认值;
// JobInfo.NETWORK_TYPE_ANY,有网络毗连 时就触发;
// JobInfo.NETWORK_TYPE_UNMETERED,非蜂窝网络中触发;
// JobInfo.NETWORK_TYPE_NOT_ROAMING,非环游 网络时才可触发;
jobBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
//设置手机充电状态下触发
jobBuilder.setRequiresCharging(true);
//设置手机处于空闲状态时触发
jobBuilder.setRequiresDeviceIdle(true);
//得到JobInfo对象
JobInfo jobInfo = jobBuilder.build();
//设置开始安排任务 ,它将返回一个状态码
//JobScheduler.RESULT_SUCCESS,乐成
//JobScheduler.RESULT_FAILURE,失败
if (mJobScheduler.schedule(jobInfo) == JobScheduler.RESULT_FAILURE) {
//安排任务 失败
}
//克制 指定JobId的工作服务
mJobScheduler.cancel(JOB_ID);
//克制 全部的工作服务
mJobScheduler.cancelAll();
}
来自:CSDN-马云龙
https://blog.csdn.net/u012124438/article/details/74617649#t3
程序员大咖整剃头 布,转载请接洽 作者得到 授权
作者:Admin本文地址:https://360admin.cn/uc-xin-shang-qi-xia-zai-de-wen-jian-zen-me-dao-chu-uc-xin-shang-qi-guan-wang-wang-zhi-dao-hang.html发布于 昨天
文章转载或复制请以超链接形式并注明出处磁力引擎导航网
觉得文章有用就打赏一下文章作者
支付宝扫一扫打赏

微信扫一扫打赏

还没有评论,来说两句吧...