如何在Eclipse中编译hierarchy viewer (基于Windows)

首先,你要保证你的手机能够开启View Server,具体见http://maider.blog.sohu.com/255448342.html
按照http://uiuno.com/2017/09/26/a114401/里的步骤操作即可将hierarchyviewer2的源码导入Eclipse并运行.
2013.3.15更新:在android源码android-4.2.2_r1分支之前,hierarchyviewer2的源码位于 SOURCE_ROOT/sdk/hierarchyviewer2文件夹内,而在android-4.2.2_r1分支之后的源代码,hierarchyviewer2的源码移至了SOURCE_ROOT/tools/swt/hierarchyviewer2文件夹内.本篇文章后续内容按照android-4.2.2_r1分支之前的代码结构讲解。而若想了解新版Android源码树的SDK工具结构,请移步:号外:Android 4.2.2 推至 AOSP master后 sdk工具大转移
(不会下载Android源码?请参考:http://maider.blog.sohu.com/250854034.html)
再仔细看下http://www.cnblogs.com/vowei/archive/2012/08/08/2627614.html这篇文章中对后台源码的分析
我现在来讲讲在Windows下,初始化AndroidDebugBridge可能会出现问题:
hierarchy viewer后台的入口点在 SOURCE_ROOT/sdk/hierarchyviewer2/app/src/com/android/hierarchyviewer/HierarchyViewerApplication.java
中的createContents(Composite parent)函数:
====================================================================================================
@Override
protected Control createContents(Composite parent) {
    // create this only once the window is opened to please SWT on Mac
    mDirector = HierarchyViewerApplicationDirector.createDirector();
    mDirector.initDebugBridge();
    mDirector.startListenForDevices();
    mDirector.populateDeviceSelectionModel();
......
===================================================================================================

以上代码做了如下工作:

1,HierarchyViewerApplicationDirector.createDirector() — 创建一个HierarchyViewerApplicationDirector对象

2,mDirector.initDebugBridge() — 初始化AndroidDebugBridge

3,mDirector.startListenForDevices() — 把mDirctor注册为AndroidDebugBridge的监听者(HierarchyViewerDirector继承了IDeviceChangeListener接口),当有设备连接、断开、改变时,mDirctor将接收到事件。

4,mDirector.populateDeviceSelectionModel() — 获取当前已经连接的设备列表,处理并显示它们。

注意,就是第二步初始化AndroidDebugBridge,在Windows下运行下,可能会失败。

原因是:mDirector是一个HierarchyViewerDirector抽象类,HierarchyViewerDirector.java位于:

SOURCE_ROOT/sdk/hierarchyviewer2/libs/hierarchyviewerlib/src/com/android/hierarchyviewerlib文件夹中。

我们来查看HierarchyViewerDirector.java中的initDebugBridge()函数:

public void initDebugBridge() {
DeviceBridge.initDebugBridge(getAdbLocation());
}

再看看getAdbLocation()函数:

public abstract String getAdbLocation();

原来只是个抽象方法,没有定义!

刚才说了,mDirector是一个HierarchyViewerDirector抽象类,而它实际上是由HierarchyViewerApplicationDirector这个类实现的。HierarchyViewerApplicationDirector.java位于SOURCE_ROOT/sdk/hierarchyviewer2/app/src/com/android/hierarchyviewer 文件夹里。

我们就来看看HierarchyViewerApplicationDirector这个类里是如何实现getAdbLocation()的:

====================================================================================================

public String getAdbLocation() {
   String hvParentLocation = System.getProperty("com.android.hierarchyviewer.bindir"); 

//$NON-NLS-1$
   // in the new SDK, adb is in the platform-tools, but when run from the command line
   // in the Android source tree, then adb is next to hierarchyviewer.
   if (hvParentLocation != null && hvParentLocation.length() != 0) {
       // check if there's a platform-tools folder
       File platformTools = new File(new File(hvParentLocation).getParent(),
               SdkConstants.FD_PLATFORM_TOOLS);
       if (platformTools.isDirectory()) {
           return platformTools.getAbsolutePath() + File.separator + SdkConstants.FN_ADB;
       }

       return hvParentLocation + File.separator + SdkConstants.FN_ADB;
   }

   return SdkConstants.FN_ADB;
}

======================================================================================

看看里面的注释你就知道了,getAdbLocation() 这段代码是以Android源码树的结构来写的,并不是以正常安装的sdk路径来写的。所以初始化AndroidDebugBridge()会失败。

于是我在HierarchyViewerDirector.java里写了个initDebugBridge的重载方法:

===================================================================================================

public void initDebugBridge() {
   DeviceBridge.initDebugBridge(getAdbLocation());
}

public void initDebugBridge(String adbLocation){
   DeviceBridge.initDebugBridge(adbLocation);
}

=======================================================================================

并且将HierarchyViewerApplication.java里的createContents函数改为:

==================================================================================================

@Override
protected Control createContents(Composite parent) {
   // create this only once the window is opened to please SWT on Mac
   mDirector = HierarchyViewerApplicationDirector.createDirector();
   mDirector.initDebugBridge("c:/Android/platform-tools/adb.exe");
   mDirector.startListenForDevices();
   mDirector.populateDeviceSelectionModel();
......
===================================================================================================
即,我在 mDirector.initDebugBridge(“c:/Android/platform-tools/adb.exe”); 指明了我电脑里adb的路径。这样,初始化adb就没问题了。
在Eclipse中运行hierachyviewer时,可能会遇到:
E/ddmlib: An established connection was aborted by the software in your host machine
java.io.IOException: An established connection was aborted by the software in your host machine
解决办法:关闭cmd中一切和adb有关的东西,重启Eclipse。
0 条评论
发表一条评论