android apk实现uiautomator脚本的运行

脚本的运行有有多种方式,可以辅助调试类运行,可以命令行运行,也可以工具直接运行今天我们来聊聊如何用android apk实现脚本的运行,以下的方式只针对于手机已经获取root权限的情况,首先我们先分析下原理:
用android studio右击run运行脚本,在控制台中会出现如下信息:

android apk实现uiautomator脚本的运行_第1张图片
image.png

下面是详细的步骤及代码:

1.build.gradle文件中添加依赖,并同步

添加入依赖如下:

androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.0'
    compile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.0'

附图如下:


android apk实现uiautomator脚本的运行_第2张图片
image.png

2.然后进行同步

3.布局文件如下:




    

4.测试类代码如下目录

android apk实现uiautomator脚本的运行_第3张图片
image.png

代码是启动qq的示例,具体的操作根据需要自行编写,示例代码如下

package com.example.administrator.excutescript;

import android.support.test.InstrumentationRegistry;
import android.support.test.uiautomator.UiAutomatorTestCase;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiSelector;

import org.junit.Test;

/**
 * Created by Administrator on 2017/9/13.
 */

public class OpenQQ  extends UiAutomatorTestCase{
    @Test
    public void  test() throws UiObjectNotFoundException {
      //以下是uiautomator1的打开qq方式
        /*  getUiDevice();
        UiObject qq=new UiObject(new UiSelector().text("QQ"));
        qq.click();*/


        //以下是uiautomator2的打开qq方式
        UiDevice uiDevice;
        uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
        uiDevice.pressHome();
        UiObject qq=uiDevice.findObject(new UiSelector().text("QQ"));
        qq.click();


    }
}

5.MainActivity代码如下

package com.example.administrator.excutescript;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {

    //声明Button按钮
    Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //找到button控件
        button=(Button) findViewById(R.id.button_1);

        //对button实现点击监控,由于是耗时操作,需要另起线程
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new OpenQQ().start();
            }
        });
    }

    class OpenQQ extends Thread{
        @Override
        public void run() {
            //class后的参数是包名+类名
            ShellUtils.execCommand("am instrument -w -r   -e debug false -e class com.example.administrator.excutescript.OpenQQ com.example.administrator.excutescript.test/android.support.test.runner.AndroidJUnitRunner",true);

        }
    }
}

6.工具类代码如下:

package com.example.administrator.excutescript;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

/**
 * Created by Administrator on 2017/7/13.
 * 有效启动shell类
 */

public class ShellUtils {

    public static final String COMMAND_SU       = "su";
    public static final String COMMAND_SH       = "sh";
    public static final String COMMAND_EXIT     = "exit\n";
    public static final String COMMAND_LINE_END = "\n";

    private ShellUtils() {
        throw new AssertionError();
    }

    /**
     * check whether has root permission
     *
     * @return
     */
    public static boolean checkRootPermission() {
        return execCommand("echo root", true, false).result == 0;
    }

    /**
     * execute shell command, default return result msg
     *
     * @param command command
     * @param isRoot whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(String command, boolean isRoot) {
        return execCommand(new String[] {command}, isRoot, true);
    }

    /**
     * execute shell commands, default return result msg
     *
     * @param commands command list
     * @param isRoot whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(List commands, boolean isRoot) {
        return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, true);
    }

    /**
     * execute shell commands, default return result msg
     *
     * @param commands command array
     * @param isRoot whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(String[] commands, boolean isRoot) {
        return execCommand(commands, isRoot, true);
    }

    /**
     * execute shell command
     *
     * @param command command
     * @param isRoot whether need to run with root
     * @param isNeedResultMsg whether need result msg
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) {
        return execCommand(new String[] {command}, isRoot, isNeedResultMsg);
    }

    /**
     * execute shell commands
     *
     * @param commands command list
     * @param isRoot whether need to run with root
     * @param isNeedResultMsg whether need result msg
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(List commands, boolean isRoot, boolean isNeedResultMsg) {
        return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, isNeedResultMsg);
    }

    /**
     * execute shell commands
     *
     * @param commands command array
     * @param isRoot whether need to run with root
     * @param isNeedResultMsg whether need result msg
     * @return 
    *
  • if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and * {@link CommandResult#errorMsg} is null.
  • *
  • if {@link CommandResult#result} is -1, there maybe some excepiton.
  • *
*/ public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) { int result = -1; if (commands == null || commands.length == 0) { return new CommandResult(result, null, null); } Process process = null; BufferedReader successResult = null; BufferedReader errorResult = null; StringBuilder successMsg = null; StringBuilder errorMsg = null; DataOutputStream os = null; try { process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH); os = new DataOutputStream(process.getOutputStream()); for (String command : commands) { if (command == null) { continue; } // donnot use os.writeBytes(commmand), avoid chinese charset error os.write(command.getBytes()); os.writeBytes(COMMAND_LINE_END); os.flush(); } os.writeBytes(COMMAND_EXIT); os.flush(); result = process.waitFor(); // get command result if (isNeedResultMsg) { successMsg = new StringBuilder(); errorMsg = new StringBuilder(); successResult = new BufferedReader(new InputStreamReader(process.getInputStream())); errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream())); String s; while ((s = successResult.readLine()) != null) { successMsg.append(s); } while ((s = errorResult.readLine()) != null) { errorMsg.append(s); } } } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } finally { try { if (os != null) { os.close(); } if (successResult != null) { successResult.close(); } if (errorResult != null) { errorResult.close(); } } catch (IOException e) { e.printStackTrace(); } if (process != null) { process.destroy(); } } return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null : errorMsg.toString()); } /** * result of command *
    *
  • {@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in * linux shell
  • *
  • {@link CommandResult#successMsg} means success message of command result
  • *
  • {@link CommandResult#errorMsg} means error message of command result
  • *
* * @author Trinea 2013-5-16 */ public static class CommandResult { /** result of command **/ public int result; /** success message of command result **/ public String successMsg; /** error message of command result **/ public String errorMsg; public CommandResult(int result) { this.result = result; } public CommandResult(int result, String successMsg, String errorMsg) { this.result = result; this.successMsg = successMsg; this.errorMsg = errorMsg; } } }

注意点:在apk启动前,必须保证脚本已经在手机中,且手机授权root

你可能感兴趣的:(android apk实现uiautomator脚本的运行)