最近看到 cpfeng0124 的关于二次开发之自动生成控件定位符,心里感概真是相当棒的思路,但是可能由于是公司的项目所以就点到为止并没有深入去解释其他一些功能。
这两天抽空研究了下吧,将部分的功能也一一的进行了研究完善。
uiautomatorviewer 的原理我就不在这里说明里,首先说一下右键单击弹出菜单。我们要动手脚的地方是

UiAutomatorView 是用来显示出截图后的界面的,

mScreenshotCanvas.addMouseListener(new MouseAdapter() {
            @SuppressWarnings("unused")
            @Override
            public void mouseUp(MouseEvent e) {
                if (mModel != null) {
                    mModel.toggleExploreMode();
                    redrawScreenshot();
                }
            }
}

我们找到这个鼠标监听事件,可以看到 readrawScreenshot() 这函数的从字面上就能明白它的作用就是将你鼠标点击的区域绘制的红色,那么我就从这里入手了,修改代码如下:

mScreenshotCanvas.addMouseListener(new MouseAdapter() {
            @SuppressWarnings("unused")
            @Override
            public void mouseUp(MouseEvent e) {
                if (mModel != null) {
                    mModel.toggleExploreMode();
                    redrawScreenshot();
                }
                //如果为鼠标右键点击那么就弹出右键菜单   
                if (e.button==3){
                    Menu menu = new Menu(mScreenshotCanvas);  
                    mScreenshotCanvas.setMenu(menu);  
                    MenuItem item = new MenuItem(menu, SWT.PUSH);  
                    item.setText("控件点击");  
                    item.addSelectionListener(new SelectionAdapter() {
                        @Override
                        public void widgetSelected(SelectionEvent e) {
                                        //获取选择的矩形区域
                            Rectangle rect = mModel.getCurrentDrawingRect();
                            objectClick(rect);  
                        };
                    });
                }
            }
        }


以上的代码就是实现右键弹出菜单,按钮叫控件点击,接着实现该按钮的点击事件,获取到所选择控件的矩形区域,进行点击操作。
那下来我们来看看到底要如何实现点击的操作呢,实际也很点击,通过 adb shell input 就可以了。

public void objectClick(Rectangle rectangle){
    String adbStr = "adb shell input tap "+(rectangle.x+rectangle.width/2)+" " +(rectangle.y+rectangle.height/2);
    execCmd(adbStr);
}

置于 execCmd 做什么操作就不用多说了,直接 java 调用 cmd 运行就可以了。

再就是一个脚本录制的功能,实际上这东西也不麻烦。只要你模范 com.android.uiautomator.actions 中的类写一个

package com.android.uiautomator.actions;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.resource.ImageDescriptor;

import com.android.uiautomator.UiAutomatorViewer;

public class RecordAction extends Action {


    private static boolean isRun = false;
    public RecordAction(UiAutomatorViewer viewer){
         super("&录制/停止");
    }

    @Override
    public ImageDescriptor getImageDescriptor() {

        if (isRun){
            return ImageHelper.loadImageDescriptorFromResource("images/stop.png");

        }else{
            return ImageHelper.loadImageDescriptorFromResource("images/play.png");
        }
    }

    @Override
    public void run() {


        if (isRun){
            StringBuffer sb = new StringBuffer();
            sb.append("if __name__ == \"__main__\":\n");
            sb.append("    unittest.main()\n");
            writeFile(sb);
            isRun = false;
            this.setImageDescriptor(ImageHelper.loadImageDescriptorFromResource("images/play.png"));
        }else{
            isRun = true;
            this.setImageDescriptor(ImageHelper.loadImageDescriptorFromResource("images/stop.png"));
            try{
                //生成部分初始化话的代码
                File file = new File("C:\\a.py");
                try{
                    file.delete();
                }catch(Exception e){
                    e.printStackTrace();
                }
                file.createNewFile();
                FileOutputStream out=new FileOutputStream(file,true);
                StringBuffer sb = new StringBuffer();
                String deviceName = getDeviceList();
                sb.append("# -*- coding: utf-8 -*-\n");
                sb.append("from appium import webdriver\n");
                sb.append("from appium.webdriver.common import touch_action\n");
                sb.append("import unittest\n");
                sb.append("class testDemo(unittest.TestCase):\n");
                sb.append("    def setUp(self):\n");
                sb.append("        desired_caps = {}\n");
                sb.append("        desired_caps['deviceName'] = '"+deviceName+"'\n");
                sb.append("        desired_caps['udid'] = '"+deviceName+"'\n");
                sb.append("        desired_caps['appPackage'] = 'com.seewo.teachercare'\n");
                sb.append("        desired_caps['platformName'] = 'Android'\n");
                sb.append("        desired_caps['platformVersion'] = '4.4.2'\n");
                sb.append("        desired_caps['appActivity'] = '.ui.TeacherMainActivity'\n");
                sb.append("        self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', desired_caps)\n");
                sb.append("    def tearDown(self):\n");
                sb.append("        self.driver.quit()\n");
                sb.append("    def testa(self):\n");
                out.write(sb.toString().getBytes("utf-8"));
                out.close();
            }catch(IOException ex){
                System.out.println(ex.getStackTrace());
            }

        }
    }


    /**
     * 获取设备列表
     * @throws IOException 
     */
    @SuppressWarnings("resource")
    private String  getDeviceList() throws IOException{
        Process p = Runtime.getRuntime().exec("cmd.exe /c adb devices");
        InputStream inStream = p.getInputStream();
        InputStreamReader inReader = new InputStreamReader(inStream,"UTF-8");
        BufferedReader inBuffer = new BufferedReader(inReader);
        String s = null;
        while((s = inBuffer.readLine()) != null){

            if(s.endsWith("device")){
                s =s.substring(0, s.lastIndexOf("device")).trim(); 
                System.out.println(s);
                return s;
            }

        }

        return null;
    }
    /**
     * 写文件操作
     * @param sb
     */
    public static void writeFile(StringBuffer sb){

        if(isRun){
            try{
                //生成部分初始化话的代码
                File file = new File("C:\\a.py");
                if(!file.exists()){
                    file.createNewFile();
                }
                FileOutputStream out=new FileOutputStream(file,true);
                out.write(sb.toString().getBytes("utf-8"));
                out.close();

            }catch(IOException ex){
                System.out.println(ex.getStackTrace());
            }
        }   
    }
}

上面有些代码我都写死了。因为这也是仓促完成,另外本人真是新手,所有代码写的烂求轻点拍。
上面主要的功能就是点击录制按钮时,初始化就写入内容,点击结束时,将 main 方法补上。其他写文件就是在右键时进行控件点击等时同时进行写文件操作就可以了。
最后在 Uiautomatorviewer 类中实例化该类

//加上按钮
toolBarManager.add(new RecordAction(this));

第一次发帖,写的可能很乱,代码也写的很渣,不知道各位能不能看的懂。


↙↙↙阅读原文可查看相关链接,并与作者交流