package io.appium.android.bootstrap.handler;
import android.os.Environment;
import com.android.uiautomator.core.UiDevice;
import io.appium.android.bootstrap.AndroidCommand;
import io.appium.android.bootstrap.AndroidCommandResult;
import io.appium.android.bootstrap.CommandHandler;
import io.appium.android.bootstrap.utils.NotImportantViews;
import java.io.File;
/**
* This handler is used to dumpWindowHierarchy.
* https://android.googlesource.com/
* platform/frameworks/testing/+/master/uiautomator
* /library/core-src/com/android/uiautomator/core/UiDevice.java
*/
@SuppressWarnings("ResultOfMethodCallIgnored")
public class DumpWindowHierarchy extends CommandHandler {
// Note that
// "new File(new File(Environment.getDataDirectory(), "local/tmp"), fileName)"
// is directly from the UiDevice.java source code.
private static final File dumpFolder = new File(Environment.getDataDirectory(), "local/tmp");
private static final String dumpFileName = "dump.xml";
private static final File dumpFile = new File(dumpFolder, dumpFileName);
private static void deleteDumpFile() {
if (dumpFile.exists()) {
dumpFile.delete();
}
}
public static boolean dump() {
dumpFolder.mkdirs();
deleteDumpFile();
try {
// dumpWindowHierarchy often has a NullPointerException
UiDevice.getInstance().dumpWindowHierarchy(dumpFileName);
} catch (Exception e) {
e.printStackTrace();
// If there's an error then the dumpfile may exist and be empty.
deleteDumpFile();
}
return dumpFile.exists();
}
/*
* @param command The {@link AndroidCommand} used for this handler.
*
* @return {@link AndroidCommandResult}
*
* @throws JSONException
*
* @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.
* bootstrap.AndroidCommand)
*/
@Override
public AndroidCommandResult execute(final AndroidCommand command) {
NotImportantViews.discard(true);
return getSuccessResult(dump());
}
}
这个方法可能在某些机器上执行到不成功而让很多人对这个方法不甚了解,而我做了很长事件的功能遍历工具的开发,专门研究过这个方法,看看我之前写的文章就理解它是做什么的啦:
dumpWindowHierarchy
它是获取当前手机界面所有控件信息,然后把树形结构保存在/data/local/tmp的目录下的dump.xml文件中,所以我们看见上面类的定义有很多关于路径、文件的字符串,就是这个原因,appium的这个DumpWindowHierarchy首先根据api的不同设置是否禁止布局压缩。如果api为18以上的,那么就启动布局压缩,这对我们获取有用的控件信息是很有作用的。然后执行dump()方法,dump方法会先创建目录,当然该目录一般都会存在,无需创建。然后删除dump.xml文件,因为要创建新的,必须删除旧的,以免获取不到控件信息的时候,dump.xml里仍然有就信息返回。然后调用
UiDevice.getInstance().dumpWindowHierarchy(dumpFileName);
将控件树信息保存在里文件中。