Hierarchy Viewer显示视图性能指标
Hierarchy Viewer默认打开“Tree View”窗口无法显示显示Performance indicators:

但选中根视图再点击按钮“Obtain layout times for tree rooted at selected node”:

就可以显示:

其上该视图性能的颜色指示符从左到右依次为:Measure、Layout和Draw,其中红色代表此树中该视图渲染最慢即占用总渲染时间的80%或其以上,绿色代表此树中该视图渲染时长小于总渲染时间的50%,黄色代表此树种该视图渲染时长50%或其以上但低于80%。

public class ProfileNodesAction extends SelectedNodeEnabledAction implements ImageAction {
...
public ProfileNodesAction() {
super("Profile Node");
ImageLoader imageLoader = ImageLoader.getLoader(HierarchyViewerDirector.class);
mImage = imageLoader.loadImage("profile.png", Display.getDefault()); //$NON-NLS-1$
setImageDescriptor(ImageDescriptor.createFromImage(mImage));
setToolTipText("Obtain layout times for tree rooted at selected node");
}
...
@Override
public void run() {
HierarchyViewerDirector.getDirector().profileCurrentNode();
}
...

public void profileCurrentNode() {
final DrawableViewNode selectedNode = TreeViewModel.getModel().getSelection();
if (selectedNode != null) {
executeInBackground("Profile Node", new Runnable() {
@Override
public void run() {
IHvDevice hvDevice = getHvDevice(selectedNode.viewNode.window.getDevice());
hvDevice.loadProfileData(selectedNode.viewNode.window, selectedNode.viewNode);
// Force the layout viewer to redraw.
TreeViewModel.getModel().notifySelectionChanged();
}
});
}
}

public static boolean loadProfileData(Window window, ViewNode viewNode) {
DeviceConnection connection = null;
try {
connection = new DeviceConnection(window.getDevice());
connection.sendCommand("PROFILE " + window.encode() + "" + viewNode.toString()); //$NON-NLS-1$
BufferedReader in = connection.getInputStream();
int protocol;
synchronized (sViewServerInfo) {
protocol = sViewServerInfo.get(window.getDevice()).protocolVersion;
}
if (protocol < 3) {
return loadProfileData(viewNode, in);
} else {
boolean ret = loadProfileDataRecursive(viewNode, in);
if (ret) {
viewNode.setProfileRatings();
}
return ret;
}
} catch (Exception e) {
Log.e(TAG, "Unable to load profiling data for window " + window.getTitle()
+ " on device " + window.getDevice());
} finally {
if (connection != null) {
connection.close();
}
}
return false;
}
private static boolean loadProfileData(ViewNode node, BufferedReader in) throws IOException {
String line;
if ((line = in.readLine()) == null || line.equalsIgnoreCase("-1 -1 -1") //$NON-NLS-1$
|| line.equalsIgnoreCase("DONE.")) { //$NON-NLS-1$
return false;
}
String[] data = line.split("");
node.measureTime = (Long.parseLong(data[0]) / 1000.0) / 1000.0;
node.layoutTime = (Long.parseLong(data[1]) / 1000.0) / 1000.0;
node.drawTime = (Long.parseLong(data[2]) / 1000.0) / 1000.0;
return true;
}
public static boolean loadProfileDataRecursive(ViewNode node, BufferedReader in)
throws IOException {
if (!loadProfileData(node, in)) {
return false;
}
for (int i = 0; i < node.children.size(); i++) {
if (!loadProfileDataRecursive(node.children.get(i), in)) {
return false;
}
}
return true;
}

public class ViewNode {
public static enum ProfileRating {
RED, YELLOW, GREEN, NONE
};
private static final double RED_THRESHOLD = 0.8;
private static final double YELLOW_THRESHOLD = 0.5;
...
public void setProfileRatings() {
final int N = children.size();
if (N > 1) {
double totalMeasure = 0;
double totalLayout = 0;
double totalDraw = 0;
for (int i = 0; i < N; i++) {
ViewNode child = children.get(i);
totalMeasure += child.measureTime;
totalLayout += child.layoutTime;
totalDraw += child.drawTime;
}
for (int i = 0; i < N; i++) {
ViewNode child = children.get(i);
if (child.measureTime / totalMeasure >= RED_THRESHOLD) {
child.measureRating = ProfileRating.RED;
} else if (child.measureTime / totalMeasure >= YELLOW_THRESHOLD) {
child.measureRating = ProfileRating.YELLOW;
} else {
child.measureRating = ProfileRating.GREEN;
}
if (child.layoutTime / totalLayout >= RED_THRESHOLD) {
child.layoutRating = ProfileRating.RED;
} else if (child.layoutTime / totalLayout >= YELLOW_THRESHOLD) {
child.layoutRating = ProfileRating.YELLOW;
} else {
child.layoutRating = ProfileRating.GREEN;
}
if (child.drawTime / totalDraw >= RED_THRESHOLD) {
child.drawRating = ProfileRating.RED;
} else if (child.drawTime / totalDraw >= YELLOW_THRESHOLD) {
child.drawRating = ProfileRating.YELLOW;
} else {
child.drawRating = ProfileRating.GREEN;
}
}
}
for (int i = 0; i < N; i++) {
children.get(i).setProfileRatings();
}
}

/**
* This class is used for connecting to a device in debug mode running the view
* server.
*/
public class DeviceConnection {
...
public void sendCommand(String command) throws IOException {
BufferedWriter out = getOutputStream();
out.write(command);
out.newLine();
out.flush();
}
...

Hierarchy Viewer显示视图性能指标的更多相关文章
- Android 实用工具Hierarchy Viewer实战
在Android的SDK工具包中,有很多十分有用的工具,可以帮助程序员开发和测试Android应用程序,大大提高其工作效率.其中的一款叫Hierachy Viewer的可视化调试工具,可以很方便地在开 ...
- Android优化——UI检视利器:Hierarchy Viewer
在Android的SDK工具包中,有很多十分有用的工具,可以帮助程序员开发和测试Android应用程序,大大提高其工作效率.其中的一款叫 Hierachy Viewer的可视化调试工具,可以很方便地在 ...
- Hierarchy Viewer
http://blog.csdn.net/ddna/article/details/5527072 Hierarchy Viewer是随AndroidSDK发布的工具,位置在tools文件夹下,名为h ...
- 看了一本书,说可以利用Hierarchy Viewer优化布局
看了一本书,说可以利用Hierarchy Viewer优化布局,今以志之. 参考:http://www.cnblogs.com/Rocky_/archive/2011/11/04/2236243.ht ...
- 【转】【Android工具】被忽略的UI检视利器:Hierarchy Viewer
原文:http://blog.csdn.net/ddna/article/details/5527072 Hierarchy Viewer是随AndroidSDK发布的工具,位置在tools文件夹下, ...
- 利用Hierarchy Viewer优化布局
好久没更新博客了,趁着清明来写点什么. 今天来讲下如何使用android中提供的工具优化我们的布局.首先我们写一个最简单的框架布局. <?xml version="1.0" ...
- Android 卡顿优化 3 布局优化 工具 Hierarchy Viewer
欲善其事, 先利其器. 分析布局, 就不得不用到Hierarchy Viewer了. 本文工具使用皆以GithubApp的详情界面RepoDetailActivity为例说明. 为了不影响阅读体验, ...
- Android工具 Hierarchy Viewer 分析
Hierarchy Viewer是随AndroidSDK发布的工具,位置在tools文件夹下,名为hierarchyviewer.bat.它是Android自带的非常有用而且使用简单的工具,可以帮助我 ...
- Android官方命令深入分析之Hierarchy Viewer
Hierarchy Viewer允许你调试和优化用户界面.它提供了一个层可视的方式来显示. 启动Hierarchy Viewer,如下: 在Android Studio中,选择Tools > A ...
随机推荐
- LinkedIn第三方登录
官方开发文档网址:https://developer.linkedin.com angularjs LinkedIn初始化 var apiKey='77n7z65hd7azmb';$(function ...
- 监听指定端口数据交互(HttpListenerContext )
很怀念以前做机票的日子,,,,可惜回不去 以前的项目中的,拿来贴贴 场景:同步第三方数据,监听指定地址(指定时间间隔,否则不满足,因为需要处理粘包问题,改篇未实现) 主要内容四个文件:下面分别说下每个 ...
- C# Activator.CreateInstance()
C#在类工厂中动态创建类的实例,所使用的方法为: 1. Activator.CreateInstance (Type) 2. Activator.CreateInstance (Type, Objec ...
- npm的镜像替换成淘宝
1.得到原本的镜像地址 npm get registry > https://registry.npmjs.org/ 设成淘宝的 npm config set registry http://r ...
- Java设计模式(学习整理)---工厂模式
1.工厂模式 1.1 为什么使用工厂模式? 因为工厂模式就相当于创建实例对象的new,我们经常要根据类Class生成实例对象,如A a=new A() 工厂模式也是用来创建实例对象的,所以以后new时 ...
- 前端模板文件化jQuery插件 $.loadTemplates
工作中使用前端模板引擎,如 artTemplate.jsRender,来替代拼接字符串. 可是直接把模板写在页面上会带来页面臃肿,模板无法重用,与 ASP.NET等后端语言语法冲突等问题. 所以将多个 ...
- MySQL5.7.9免安装版配置方法
1. 解压MySQL压缩包 将下载的MySQL压缩包解压到自定义目录下,我的解压目录是: "D:\Program Files\mysql-5.7.9-win32" ...
- 一站式远程页面调试工具spy-debugger 2.0,已支持HTTPS
项目名称: spy-debugger 项目地址:https://github.com/wuchangming/spy-debugger 关于spy-debugger npm Build Status ...
- 多选select实现左右添加删除
案例:实现效果 1.选择监控城市,车辆列表显示对应城市所有车辆 2.从左边选择车辆 单击 >> 实现右侧显示添加车辆 ,左侧对应移除已选择车辆 3.右侧选中车辆 单击 &l ...
- 安卓AVD使用建议
问题描述:之前在安装了Android开发环境后,一开始并没有直接在Android手机和平板上进行调试,是使用的AVD模拟器工具.由于电脑的配置不是特别好,总感觉AVD的使用速度太慢,包括启动的时候还有 ...