In fact, there are many related articles online, but on the real machine to open the view server's Chinese article seems to have only one, the previous period of time in accordance with the content of this article, and combined with the English source to hack my Nexus S (4.1.2) also went a little detour. Now summarize my steps (in fact there are quite a few copies of this article, heartfelt thanks to the original author). and write a script that monkeyrunner after the view server is opened.
Let's start with the background, Monkeyrunner as an automated test for Android system tools in some cases or easier than robotium, However, Monkeryrunner to determine whether the test results are correct method is the actual test of the screen and pre-cut the correct screen to do the match! This approach is not flexible enough. If the returned result is displayed in a text box, I can remove the string from the text box and compare it directly to the expected string, which makes it much more convenient.
The Android SDK comes with a tool called monitor, which hierarchy Viewer can see the app's UI structure, control properties, and so on. Monkeyrunner has a class by through which you can locate the control in code based on the control ID to write more targeted code (such as clicking a button, such as getting a string in a text box).
For security reasons, however, the Hierarchy Viewer can only connect to Android-developed phones or simulators. Only when a service called View server is launched on the device or emulator can the Hierarchy Viewer communicate with the socket to see the app's "View". The vast majority of commercial mobile phones are unable to open the view server, so the hierarchy Viewer will not be able to connect to ordinary commercial phones. And by is dependent on the hierarchy Viewer, so if you want to do something with the control ID on a normal commercial phone, the connection simulator runs through the script to connect the real machine run is wrong.
However, the Xiaomi phone is an exception, you can easily open its view Server by executing the following command:
ADB Shell Service Call window 1 i32 4939
Then decide whether to turn on view Server by executing the following command:
ADB Shell Service Call window 3
If the return value is: Result:parcel (00000000 00000001 ' ... ') indicates that view server is turned on
If the return value is: Result:parcel (00000000 00000000 ' ... ') indicates that view server is turned off
If you want to close view server, execute the following command:
ADB Shell Service Call window 2 i32 4939
Other than Xiaomi mobile phone, can not open view Server? After a survey and practice, in fact, as long as the root, and equipped with BusyBox mobile phone, by modifying a mobile phone/system/framework in a file, you can open the view Server.
Here is my summary of the steps to open View server (reminder: If you follow my steps to cause your phone to brick, I am not responsible for):
1. Preparatory work
A. Unlock your phone and swipe into a third-party recovery. This step is not required to open the view server. But in case the phone does not start normally, you can restore the phone system through the RESTORE function in the third party recovery, provided that you make a backup through the backup function before modifying the system files.
B.root mobile phone. Root is the ability to read and write access to your phone's system files, so you can modify the system files that are not allowed to open the view server.
C. Install the BusyBox app on your phone. We'll use it when we sign the generated Odex file.
D. Use a third-party recovery to back up the phone system. This step is not a required step.
E. Create the Hack folder under D, download the Baksmali-1.4.2.jar, Smali-1.4.2.jar, Zip.exe, and dexopt-wrapper tools and save them under D:\hack.
2. Start hack (again: Make sure to carefully read all the text in each of the following steps before starting the operation)
A. Connect your phone to your PC via USB to ensure that the ADB service is functioning properly.
B. Back up the files in/system/framework/on your phone to your PC. When backing up, make sure the folder structure of the backup file on the PC is the same as the/system/framework in the phone, such as creating the Hack\system\framework folder structure on the D drive and then running
ADB pull/system/framework D:\hack\system\framework
C. Enter adb shell and output bootclasspath:
Echo $BOOTCLASSPATH
The output path is then temporarily saved. Mine is (the $bootclasspath of every machine is not necessarily the same):
/system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/ framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/ Services.jar:/system/framework/apache-xml.jar
D. Enter D:\hack in the Command Line window, and then run the Services.odex file under Baksmali decompile \system\framework:
Java-jar baksmali-1.4.2.jar–x-a <api level>–c <local bootclasspath> system\framework\services.odex
Parameter explanation: Https://code.google.com/p/smali/wiki/DeodexInstructions
Specifically, the "-a" followed by the number, indicating your system's API level (related to your system version). The control relationship between the system version and the API level is as follows:
This step in the command on my machine (version 4.1.2) is:
Java-jar Baksmali-1.4.2.jar-x-a 16-c System\framework\core.jar:system\framework\core-junit.jar:system\framework\ Bouncycastle.jar:system\framework\ext.jar:system\framework\framework.jar:system\framework\android.policy.jar: System\framework\services.jar:system\framework\apache-xml.jar System\framework\services.odex
If this step succeeds, under D:\hack, there will be an out folder generated.
Note that the-C followed by a local backup of the jar package path, the previous step in the path of the staging system "/" removed, the other "/" replaced by "\".
Here, by the way, please explain the Dex file, the Odex file, and the Smali file:
- Dex File: Dex is the full name of the Dalvik VM executes, the Android Dalvik execution program, not the Java bytecode but the Dalvik bytecode, 16 binary machine instructions.
- Odex file: The Dex file is optimized for specific models, resulting in the optimized Dex file, which increases the speed of the software and reduces the RAM footprint when the software runs.
- Smali file: Converts the Dex file into a readable code form and decompile the general format of the file.
E. Open the Out\com\android\server\wm\windowmanagerservice.smali file with Eclipse Find. Method private Issystemsecure () Z This function, Add the "Const/4 V0, 0x0" line between the last 7, 8 lines ": Goto_21" and "return V0" in this code.
The last few lines of the. Method Private issystemsecure () Z function become:
If-eqz V0,: cond_22
CONST/4 V0, 0x1
: goto_21
CONST/4 V0, 0x0
Return V0
: cond_22
CONST/4 V0, 0x0
Goto:goto_21
. End method
F. Now run Smali, recompile:
Java-jar Smali-1.4.2.jar-o Classes.dex out
At this time, the Classes.dex file should appear in the D:\hack folder
G. Use the Zip tool to make the generated classes.dex into a jar package
Zip.exe Services_hacked.jar Classes.dex
H. Enter the adb shell, type su and enter to get root privileges
I. then input mount | Grep/system See which partition is attached to the/system, for example mine is:
/dev/block/platform/s3c-sdhci.0/by-name/system/system ext4 ro, relatime,barrier=1,data=ordered 0 0
J. then enter the following command to mount the/system again and change the/system permissions (replace "/dev/block/platform/s3c-sdhci.0/by-name/system" with your/system mount partition):
Mount-o Remount/dev/block/platform/s3c-sdhci.0/by-name/system/system
This step is intended to replace the Services.odex in/system/framework with the P-step in the back.
K. Re-enter Mount | Grep/system confirmed that/system has been changed to writable (formerly "Ro", Now "RW")
L. Copy Services_hacked.jar and Dexopt-wrapper to the/data/local/tmp folder in your phone
ADB push d:\hack\services_hacked.jar/data/local/tmp
ADB push d:\hack\dexopt-wrapper/data/local/tmp
M. Enter the ADB shell, and after you enter Su , change the Dexopt-wrapper permissions to 777
chmod 777/data/local/tmp/dexopt-wrapper
N.cd to the/data/local/tmp folder, run:
Bootclasspath/dexopt-wrapper/services_hacked.jar/services_hacked.odex <c step, but excluded ":/system/framework/ Services.jar ">
This step in the command on my machine is:
./dexopt-wrapper./services_hacked.jar./services_hacked.odex/system/framework/core.jar:/system/framework/ core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/ System/framework/android.policy.jar:/system/framework/apache-xml.jar
This creates the Services_hacked.odex file in the/data/local/tmp folder
O. Create a Services_hacked.odex signature for ourselves:
BusyBox DD if=/system/framework/services.odex of=/data/local/tmp/services_hacked.odex bs=1 count=20 skip=52 seek=52 Conv=notrunc
Parameter explanation:
- If-input file
- Of-output file
- Bs-block size (1 byte)
- Count-number of Blocks
- Skip-input file Offset
- Seek-output file Offset
- Conv=notrunc-don ' t truncate the output file.
P. Replace the Services.odex in/system/framework with our own services_hacked.odex
DD If=/data/local/tmp/services_hacked.odex Of=/system/framework/services.odex
A little later, the phone will restart automatically.
Q. After a successful restart, use the following command to open the view Server:
ADB Shell Service Call window 1 i32 4939
R. Use the following command to see if view server is turned on:
ADB Shell Service Call window 3
The returned value is Result:parcel (00000000 00000001 ' ... '), then you have successfully opened the view server!
3. Disaster recovery
If you unfortunately in the last section of the P-step phone restart not home, has been in the Bootloop state, do not use the way to restart the phone battery . You can already use ADB at this time and execute it in the Command line window:
ADB push D:\hack\system\framework\services.odex/system/framework/services.odex
You can then copy the Services.odex back, so that the phone will be able to enter the home.
If you restart your phone very accidentally, you will find that neither the home nor the ADB can be used, then only the third party's recovery, using the previous backup to restore the mobile phone system.
The following is how to use the Hierarchyviewer and by these two classes to flexibly complete the Monkeyrunner script (Monkeyrunner's other basic code here does not repeat).
First assume a scene, there is an app, open after a button, click on this button, the normal situation will be in the following text box to return "OK". We need to use the code to achieve the click of this button, and then get the return value in the text box and the expected result "OK" to do the match.
We see in the hierarchy Viewer above that the ID of the button in the app is "Id/button" and the ID of the text box is "Id/output".
In order to manipulate the phone with the control ID, we need to import these two classes at the beginning of the code:
From Com.android.monkeyrunner.easy Import by
From Com.android.chimpchat.hierarchyviewer import Hierarchyviewer
Then get the button object using the following code:
Hierarchyviewer = Device.gethierarchyviewer ()
Viewnodebutton = Hierarchyviewer.findviewbyid ("Id/button")
Get the center coordinates of the button using the following code:
Pointbutton = Hierarchyviewer.getabsolutecenterofview (Viewnodebutton)
This time pointbutton.x is the center of the button axis, POINTBUTTON.Y is the center of the button ordinate, but with these two coordinates, we can not directly use Device.touch (x, y, "down_and_up") way to point this button , because this coordinate is based on the screen resolution of the phone when developing the app, so we need to convert it to know what the central coordinates of the button are on the current test phone.
The screen resolution at design time (for example, 320 and 533) is detected by the hierarchy Viewer, and is defined in the code:
Originalresolutionwidth = 320
Originalresolutionheight = 533
Then get the screen resolution of your current test phone via the Monkeydevice API:
actualresolutionwidth = Int (Device.getproperty ("Display.width"))
actualresolutionheight = Int (Device.getproperty ("Display.height"))
Then use the following code to get the resolution of the target phone and the resolution of the development design ratio:
Xratio = float (actualresolutionwidth)/Originalresolutionwidth
Yratio = float (actualresolutionheight)/Originalresolutionheight
With Xratio and yratio, we can easily point to the correct coordinates with the following code:
Device.touch (int (pointregister.x * xratio), int (POINTREGISTER.Y * yratio), "down_and_up")
After the button point, we need to get the return value in the text box using the following code:
Viewnodeoutput = Hierarchyviewer.findviewbyid ("Id/output")
Output = ViewNodeOutput.namedProperties.get ("Text:mtext"). Value
So we can compare the output with the expected "OK":
if output = = "OK":
Print "Success"
Else
Print "Fail"
Finally add a sentence about unittest, if you want to follow the Python unittest framework to write test cases, will use the
Self.assertequals (expectedstring, actualstring)
Such statements , if it is a Chinese operating system, when running may appear lookuperror:unknown encoding gbk such errors, please refer to the Android Automated Test learning notes provided in the method to solve.
Update 20130912:
If you want to click the label in the menu, you will find all the same ID names. What about this time? Maybe you can use Device.press (' Keycode_dpad_up/down/left/right ') method to navigate to the label you need to click, but I haven't tried it.
with a third-party package androidviewclient, you can use the text on the label to navigate to the label you want to click.
1. Download the binary jar and place it under Sdk\tools\lib
2. In the py file from com.dtmilano.android.viewclient import viewclient
3. Then device, Serialno = Viewclient.connecttodeviceorexit (), initiates an activity with viewclient = Viewclient (device, Serialno) and Viewclient.dump () can get all the controls, and then the text will find the desired control. Please refer to http://blog.csdn.net/jiguanghoverli/article/details/10189401, HTTPS://GITHUB.COM/DTMILANO/ANDROIDVIEWCLIENT/ISSUES/22 for details.
If you see exception:adb= "Adb.exe" is not executable during the run. Did you forget to set android_home in the environment? This error, put Adb.exe under C:\Windows\system32\.
In addition, the introduction of this third-party package also has the advantage that in testing some apps do not have to consider the resolution of the problem (at the moment I have to click on the menu in an app does not need to consider the resolution of the label, no investigation is due to the reason of the menu, or the development mechanism of different apps).
Update 20130913:
In the Windows Chinese system, even according to the text link in the method to solve the Lookuperror:unknown encoding gbk such errors, but encountered the real Chinese (if not "solve", even if the assert is in English, will also report the above error) or will be errors, such as Assertionerror: ' \xe5\x9f\x8e\xe5\xb8\x82 '! = U ' \u57ce\u5e02 ', this time need to be compared to the string encode ("UTF-8"), please refer to HTTP://1. vb.blog.163.com/blog/static/104546220071113105047729/
Turn on the real Machine view server introduce hierarchyviewer/by write Monkeyrunner automated test script