monkeyrunner内置uiautomator出错的原因

之前做app功能遍历的项目中使用的是monkeyrunner+hierarchyviewer的方式,但是hierarchyviewer提供的信息太多而且无用的信息居多,所以想换成monkeyrunner+uiautomatorviewer的方式来做。但是在集合的时候调用monkeyrunner和uiautomator时出错:


public void test_Exception() {
		System.setProperty("com.android.uiautomator.bindir", "D:/sdk/tools");
		DebugBridge.init();
		
		MyDeviceManager manager = null;
		IDevice idevice = null;
		try {
			Thread.sleep(3000);
			List<IDevice> devices = DebugBridge.getDevices();
			idevice = devices.get(0);
			manager = new MyDeviceManager(idevice);
			getUIHierarchy(idevice);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			manager.dispose();
			DebugBridge.terminate();
		}
	}

	private void getUIHierarchy(IDevice idevice) {
		String path = System.getProperty("user.dir") + File.separator + "xml" + File.separator + "uidump.xml";
		String command = String.format("%s %s %s", new Object[] { "/system/bin/uiautomator", "dump",
				"/data/local/tmp/qianhui.xml" });
		CountDownLatch commandCompleteLatch = new CountDownLatch(1);
		try {
			idevice.executeShellCommand(command, new CollectingOutputReceiver(commandCompleteLatch), 40000);
			commandCompleteLatch.await(40L, TimeUnit.SECONDS);
			System.out.println("Pull UI XML snapshot from device...1212");
			idevice.getSyncService().pullFile("/data/local/tmp/qianhui.xml", path, SyncService.getNullProgressMonitor());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

在MyDeviceManager构造方法中执行的是创建monkey对象:


public MyDeviceManager(IDevice iDevice) {
		this.mIDevice = iDevice;
		this.mAdbChimpDevice = new AdbChimpDevice(iDevice);
		/*String width = mAdbChimpDevice.getProperty("display.width");
		System.out.println(width);
		String height = mAdbChimpDevice.getProperty("display.height");
		System.out.println(height);
		sWidth = Integer.parseInt(width);
		sHeight = Integer.parseInt(height);*/

	}

当我执行上面的代码时报错:


06-01 17:06:47.897: E/AndroidRuntime(3007): *** FATAL EXCEPTION IN SYSTEM PROCESS: main
06-01 17:06:47.897: E/AndroidRuntime(3007): java.lang.IllegalStateException: UiAutomationService android.accessibilityservice.IAccessibilityServiceClient$Stub$Proxy@421baa38already registered!
06-01 17:06:47.897: E/AndroidRuntime(3007): 	at android.os.Parcel.readException(Parcel.java:1473)
06-01 17:06:47.897: E/AndroidRuntime(3007): 	at android.os.Parcel.readException(Parcel.java:1419)
06-01 17:06:47.897: E/AndroidRuntime(3007): 	at android.view.accessibility.IAccessibilityManager$Stub$Proxy.registerUiTestAutomationService(IAccessibilityManager.java:342)
06-01 17:06:47.897: E/AndroidRuntime(3007): 	at android.app.UiAutomationConnection.registerUiTestAutomationServiceLocked(UiAutomationConnection.java:175)
06-01 17:06:47.897: E/AndroidRuntime(3007): 	at android.app.UiAutomationConnection.connect(UiAutomationConnection.java:72)
06-01 17:06:47.897: E/AndroidRuntime(3007): 	at android.app.UiAutomation.connect(UiAutomation.java:188)
06-01 17:06:47.897: E/AndroidRuntime(3007): 	at com.android.uiautomator.core.UiAutomationShellWrapper.connect(UiAutomationShellWrapper.java:32)
06-01 17:06:47.897: E/AndroidRuntime(3007): 	at com.android.commands.uiautomator.DumpCommand.run(DumpCommand.java:74)
06-01 17:06:47.897: E/AndroidRuntime(3007): 	at com.android.commands.uiautomator.Launcher.main(Launcher.java:83)
06-01 17:06:47.897: E/AndroidRuntime(3007): 	at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
06-01 17:06:47.897: E/AndroidRuntime(3007): 	at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:271)
06-01 17:06:47.897: E/AndroidRuntime(3007): 	at dalvik.system.NativeStart.main(Native Method)
06-01 17:06:47.907: E/ServiceManager(3007): error in getService
06-01 17:06:47.907: E/ServiceManager(3007): android.os.RemoteException: Unknown binder error code. 0xfffffff7
06-01 17:06:47.907: E/ServiceManager(3007): 	at android.os.BinderProxy.transact(Native Method)
06-01 17:06:47.907: E/ServiceManager(3007): 	at android.os.ServiceManagerProxy.getService(ServiceManagerNative.java:123)
06-01 17:06:47.907: E/ServiceManager(3007): 	at android.os.ServiceManager.getService(ServiceManager.java:55)
06-01 17:06:47.907: E/ServiceManager(3007): 	at android.app.ActivityManagerNative$1.create(ActivityManagerNative.java:2152)
06-01 17:06:47.907: E/ServiceManager(3007): 	at android.app.ActivityManagerNative$1.create(ActivityManagerNative.java:2150)
06-01 17:06:47.907: E/ServiceManager(3007): 	at android.util.Singleton.get(Singleton.java:34)
06-01 17:06:47.907: E/ServiceManager(3007): 	at android.app.ActivityManagerNative.getDefault(ActivityManagerNative.java:76)
06-01 17:06:47.907: E/ServiceManager(3007): 	at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:86)
06-01 17:06:47.907: E/ServiceManager(3007): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
06-01 17:06:47.907: E/ServiceManager(3007): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
06-01 17:06:47.907: E/ServiceManager(3007): 	at dalvik.system.NativeStart.main(Native Method)
06-01 17:06:47.917: I/Process(3007): Sending signal. PID: 3007 SIG: 9
06-01 17:06:47.917: E/AndroidRuntime(3007): Error reporting crash
06-01 17:06:47.917: E/AndroidRuntime(3007): java.lang.NullPointerException
06-01 17:06:47.917: E/AndroidRuntime(3007): 	at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:86)
06-01 17:06:47.917: E/AndroidRuntime(3007): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
06-01 17:06:47.917: E/AndroidRuntime(3007): 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
06-01 17:06:47.917: E/AndroidRuntime(3007): 	at dalvik.system.NativeStart.main(Native Method)

而当我把

manager = new MyDeviceManager(idevice);
getUIHierarchy(idevice);

的位置调换一下,执行成功。所以我怀疑monkeyrunner在启动的时候已经创建了uiautomator的对象,才会造成上面的提示错误,所以我试图去查看一下monkeyrunner到底有没有做这件事。


查看AdbChimpDevice创建的源码,发现


String command = new StringBuilder().append("monkey --port ").append(port).toString();
    executeAsyncCommand(command, new LoggingOutputReceiver(LOG, Level.FINE));


这一步是打开monkey,在cmd下执行该命令就能知道:


monkeyrunner内置uiautomator出错的原因_第1张图片


通过这条命令我找到了system/bin下的monkey脚本:


# Script to start "monkey" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/monkey.jar
trap "" HUP
exec app_process $base/bin com.android.commands.monkey.Monkey $*


monkeyrunner内置uiautomator出错的原因_第2张图片


然后用dex2jar工具将其编译成classes_dex2jar.jar,然后用JD-GUI打开。


monkeyrunner内置uiautomator出错的原因_第3张图片


找到了执行的方法,但是没发现执行uiautomator的函数。继续看AdbChimpDevice里方法一路跟踪到ChimpManager这个类,在AdbChimpDevice执行力该类的wake()方法:


  public void wake()
    throws IOException
  {
    sendMonkeyEvent("wake");
  }

private String sendMonkeyEventAndGetResponse(String command)
    throws IOException
  {
    command = command.trim();
    LOG.info(new StringBuilder().append("Monkey Command: ").append(command).append(".").toString());

    this.monkeyWriter.write(new StringBuilder().append(command).append("\n").toString());
    this.monkeyWriter.flush();
    return this.monkeyReader.readLine();
  }

最终向12345端口的socket发送了一条wake的命令。


monkeyrunner内置uiautomator出错的原因_第4张图片


很不幸,被我言中了。看来将uiautomator内置进来,还不是一件轻松的事情!



你可能感兴趣的:(android,UiAutomator)