Android tool hierarchyviewer code introduction (1)-function implementation demonstration

Source: Internet
Author: User

Hierarchyviewer is a very useful tool in the android SDK package. You can find it in the Android-sdks/tools directory. Through hierarchyviewer, even if there is no source code for the application, we can intuitively browse the hierarchical structure of controls in the activity, as well as the attributes and, this is very helpful for testers to compile automated test cases. In this series of articles, we will read and parse the hierarchyviewer code to learn how hierarchyviewer works, and to learn more about the interfaces provided by Android to developers. The code of this series of articles is based on the source code of android4.0. If you haven't downloaded the source code, download it. The journey begins.

The first step of this article is not to start from the source code reading, but to demo and explain the main working principles of hierarchyviewer. This is the essence of the source code extracted by the author :). After reading this article, you can write your own simple hierarchyviewer. We will mainly explain the following parts:

1. How to connect to viewserver

2. How to obtain activity activities

3. How to obtain the control tree of an activity

4. How to obtain

 

How to connect to viewserver

Viewserver is a service provided by Android through port 4939. hierarchyviewer mainly obtains activity information through it. hierarchyviewer connects to viewserver through the following three things. This requires ADB. In hierarchyviewer, ADB is called directly through the API. Here we first use the command line ADB to implement the same function.

(1) forword port. It is to map port 4939 on the Android device to a port on the PC. In this way, packets sent to the port on the PC will be forwarded to port 4939 on the Android device.

First, enter the command to list all Android devices.

?
1 adb devices

 

Suppose we have multiple devices connected to the PC, and the output of this command is:

?
123 List of devices attached
emulator-5554   deviceemulator-5556   device

 

Take the device emulator-5556 as an example. Next we map its port 4939 to port 4939 of the PC:

?
1 adb -s emulator-5556 forward tcp:4939 tcp:4939

If multiple Android devices are connected, hierarchyviewer maps port 4939 of the next Android device to port 4940 of the PC, and so on.

 

(2) Open the viewserver service.

First, you need to determine whether the viewserver is Enabled:

?
1 adb -s emulator-5556 shell service call window 3

 

If the returned value is "Result: parcel (00000000 00000000 '...')", it indicates that viewserver is not enabled. Use the following command to open viewserver:

?
1 adb -s emulator-5556 shell service call window 1 i32 4939

 

The command to disable viewserver is:

?
1 adb -s emulator-5556 shell service call window 2 i32 4939

 

(3) connect to viewserver. Since viewserver has been enabled, we need to connect to it next. Because we have mapped the emulator-5556 port to port 4939 of the PC, we need to connect 127.0.0.1: 4939. You need to write some java code:

?
1234567891011 import
java.net.*;
 try{    Socket socket =
new Socket();    socket.connect(new
InetSocketAddress("127.0.0.1",
4939),40000);    BufferedWriter out =
new BufferedWriter(new
OutputStreamWriter(socket.getOutputStream()));    BufferedReader in =
new BufferedReader(new
InputStreamReader(socket.getInputStream(), "utf-8"));} } catch
( Exception e ) {      e.printStackTrace();
}

Out and in are used to send commands and receive returned data. Note that the communication between hierarchyviewer and viewserver uses short connections. Therefore, each command sent requires a new connection, therefore, the above code needs to be called repeatedly.

 

How to obtain activity

When hierarchyviewer is enabled, the list of active activities of each device is displayed, for example:

 

How is this implemented? You need to send the "list" command to viewerserver and check the following code:

?
1234567891011121314 //send ‘LIST’ commandout.write("LIST");out.newLine();out.flush(); //receive response from viewserverString context="";String line;while
((line = in.readLine()) !=
null) {            if
("DONE.".equalsIgnoreCase(line)) {
//$NON-NLS-1$                break;            }            context+=line+"\r\n";}

 

We can obtain a list similar to the following:

?
1234567891011 44fd1b78 com.android.internal.service.wallpaper.ImageWallpaper4507aa28 com.android.launcher/com.android.launcher2.Launcher45047328 com.tencent.mobileqq/com.tencent.mobileqq.activity.HomeActivity450b8d18 com.tencent.mobileqq/com.tencent.mobileqq.activity.NotificationActivity451049c0 com.tencent.mobileqq/com.tencent.mobileqq.activity.NotificationActivity451167a8 com.tencent.mobileqq/com.tencent.mobileqq.activity.UpgradeActivity450efef0 com.tencent.mobileqq/com.tencent.mobileqq.activity.UpgradeActivity4502f2e0 TrackingView4503f560 StatusBarExpanded44fe0bb0 StatusBar44f09250 Keyguard

Note that the hexadecimal number in front of each row is a hashcode. We need to use this hashcode when further requesting the control tree corresponding to the activity.

 

How to obtain the control tree of an activity
After an activity is selected, hierarchyviewer obtains its control and displays it as a hierarchy chart:

 

The command for obtaining control tree information is dump, followed by the corresponding activity hash code. If ffffffff is used as the parameter, the front-end activity is used. Take com. Android. launcher2.launcher as an example. Its hash code is ipv7aa28. Check the Code:

?
12345678910111213 //out.write("DUMP ffffffff");out.write("DUMP 4507aa28");out.newLine();out.flush();         String context1="";line="";while ((line = in.readLine()) != null) {    if ("DONE.".equalsIgnoreCase(line)) { //$NON-NLS-1$        break;    }    context1+=line+"\r\n";}

 

The returned control tree is saved in the text context1. Generally, the content of the text is very large. I will not print it all here. Let's just take one of the lines to see it:

?
1 android.widget.FrameLayout@44edba90 mForeground=52,android.graphics.drawable.NinePatchDrawable@44edc1e0 mForegroundInPadding=5,false mForegroundPaddingBottom=1,0 mForegroundPaddingLeft=1,0 mForegroundPaddingRight=1,0
mForegroundPaddingTop=1,0 mMeasureAllChildren=5,false mForegroundGravity=2,55 getDescendantFocusability()=24,FOCUS_BEFORE_DESCENDANTS getPersistentDrawingCache()=9,SCROLLING isAlwaysDrawnWithCacheEnabled()=4,true isAnimationCacheEnabled()=4,true isChildrenDrawingOrderEnabled()=5,false
isChildrenDrawnWithCacheEnabled()=5,false mMinWidth=1,0 mPaddingBottom=1,0 mPaddingLeft=1,0 mPaddingRight=1,0 mPaddingTop=2,38 mMinHeight=1,0 mMeasuredWidth=3,480 mMeasuredHeight=3,800 mLeft=1,0 mPrivateFlags_DRAWING_CACHE_INVALID=3,0x0 mPrivateFlags_DRAWN=4,0x20
mPrivateFlags=8,16911408 mID=10,id/content mRight=3,480 mScrollX=1,0 mScrollY=1,0 mTop=1,0 mBottom=3,800 mUserPaddingBottom=1,0 mUserPaddingRight=1,0 mViewFlags=9,402653186 getBaseline()=2,-1 getHeight()=3,800 layout_bottomMargin=1,0 layout_leftMargin=1,0
layout_rightMargin=1,0 layout_topMargin=1,0 layout_height=12,MATCH_PARENT layout_width=12,MATCH_PARENT getTag()=4,null getVisibility()=7,VISIBLE getWidth()=3,480 hasFocus()=5,false isClickable()=5,false isDrawingCacheEnabled()=5,false isEnabled()=4,true isFocusable()=5,false
isFocusableInTouchMode()=5,false isFocused()=5,false isHapticFeedbackEnabled()=4,true isInTouchMode()=4,true isOpaque()=5,false isSelected()=5,false isSoundEffectsEnabled()=4,true willNotCacheDrawing()=5,false willNotDraw()=5,false

Each row in the returned text is a control in the activity, which contains all the information of the Control. hierarchyviewer parses the information and displays it in the attribute list. Note that each row contains a "control type @ hash code" field at the beginning, such as Android. widget. framelayout @ 44edba90, which is used to obtain the screen of the control.

How does hierarchyviewer parse this text into a hierarchy chart? It turns out that there are several spaces in front of each line. For example, if there are five spaces in front of each line, it indicates that the control is on the sixth layer, the last four spaces indent control is its parent control. In the articles after this series, we will read how hierarchyviewer parses the text and shows the hierarchy chart.

 

How to obtain

When a control is selected on the hierarchy chart, hierarchyviewer displays the control:

 

The obtained command is capture. You need to pass the hashcode of the activity and the hashcode of the control as the parameter. See the following code:

?
12345678 import
org.eclipse.swt.graphics.Image;
import
org.eclipse.swt.widgets.Display;
 out.write("CAPTURE 4507aa28 android.widget.FrameLayout@44edba90");out.newLine();out.flush(); Image image =
new Image(Display.getDefault(), socket.getInputStream());

 

So far, I believe that you have a basic understanding of the main implementation mechanisms of hierarchyviewer. Next, we will really start to read the hierarchyviewer code. The content of the following chapters is probably:

Use eclipse to read and debug hierarchyviewer

Guide to hierarchyviewer background code

Hierarchyviewer front-end code reading

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.