实现了一个uiautomator玩玩

179 阅读2分钟

由于android sdk monitor里面uiautomator在高版本已经打不开了,然后引入了以下思考

1. PC端独立编译

在github找到了以下项目

github.com/TarCV/uiaut…

image.png

2. 自己实现一个不需要引入依赖的uiautomator

找到一个adb shell命令,可以用于生成view tree信息xml

adb shell uiautomator dump
adb pull /sdcard/window_dump.xml /Users/zjw/IdeaProjects/untitled/src/window_dump.xml

image.png

然后就是写代码解析Node根据坐标反向生成UI

代码逻辑就交给trae ai实现了 我稍微润色一下 ai监工实锤了-。-

import javax.swing.*;
import java.awt.*;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

//命令行 adb shell uiautomator dump
// adb pull /sdcard/window_dump.xml /Users/zjw/IdeaProjects/untitled/src/window_dump.xml
public class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame("手机界面布局图");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        // 创建自定义面板
        JPanel panel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                drawLayout(g);
            }
        };
        
        // 设置面板大小为实际内容大小
        panel.setPreferredSize(new Dimension(1080, 2400));
        
        // 创建滚动面板
        JScrollPane scrollPane = new JScrollPane(panel);
        scrollPane.setPreferredSize(new Dimension(540, 1200));
        
        // 设置滚动条策略
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        
        // 启用滚轮滚动
        scrollPane.setWheelScrollingEnabled(true);
        
        frame.add(scrollPane);
        frame.pack();
        frame.setLocationRelativeTo(null); // 窗口居中显示
        frame.setVisible(true);
    }
    
    private static void drawLayout(Graphics g) {
        try {
            File inputFile = new File("src/window_dump.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(inputFile);
            doc.getDocumentElement().normalize();
            
            // 获取所有node元素
            NodeList nodeList = doc.getElementsByTagName("node");
            
            // 遍历所有节点
            for (int i = 0; i < nodeList.getLength(); i++) {
                Element element = (Element) nodeList.item(i);
                String bounds = element.getAttribute("bounds");
                if (!bounds.isEmpty()) {
                    // 解析bounds字符串 [x1,y1][x2,y2]
                    bounds = bounds.replace("][", ",").replace("[", "").replace("]", "");
                    String[] coordinates = bounds.split(",");
                    int x1 = Integer.parseInt(coordinates[0]) / 2;
                    int y1 = Integer.parseInt(coordinates[1]) / 2;
                    int x2 = Integer.parseInt(coordinates[2]) / 2;
                    int y2 = Integer.parseInt(coordinates[3]) / 2;
                    
                    // 绘制布局占位背景
                   // g.setColor(new Color(0, 0, 255, 30));
                    //g.fillRect(x1, y1, x2 - x1, y2 - y1);
                    //绘制布局边框
                    g.setColor(new Color(255, 0, 0, 128));
                    g.drawRect(x1, y1, x2 - x1, y2 - y1);
                    
                    // 绘制文本
                    String text = element.getAttribute("text");
                    if (!text.isEmpty()) {
                        g.setColor(Color.BLACK);
                        g.drawString(text, x1 + 5, y1 + 15);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

进一步甚至可以把调用adb shell命令写进去,太懒了这一步就省略了

看看效果

image.png

是不是有系统工具那味了,hhh