• 老李推荐:第8章3节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-启动AndroidDebugBridge 3


    首先它通过查找JVM中的System Property来找到"com.android.monkeyrunner.bindir"这个属性的值,记得前面小节运行环境初始化的时候在monkeyrunner这个shell脚本里面它是怎么通过java的-D参数把该值保存到JVM里面的吧?其实它就是你的文件系统中保存sdk的monkeyrunner这个bin(shell)文件的路径,在我的机器上是"com.android.monkeyrunner.bindir:/Users/apple/Develop/sdk/tools".

    找到这个路径后通过第82行的代码再取得它的父目录,也就是sdk的目录,再加上'platform-tools'这个子目录,然后再通过85或者88这行加上adb这个名字,这里的FN_ADB就是adb的名字,在windows下会加上个'.exe'变成'adb.exe' ,类linux系统下就只是‘adb’。在本人的机器里面就是"Users/apple/Develop/sdk/platform-tools/adb"

    好,找到了adb所在路经后,AdbBackend的构造函数就会根据这个参数去调用AndroidDebugBridge的createBridge这个静态方法:

    265 public static AndroidDebugBridge createBridge()
    ...
    271 try
    272 {
    273 sThis = new AndroidDebugBridge();
    274 sThis.start();
    275 } catch (InvalidParameterException e) {
    276 sThis = null;
    277 }
    ...
    297 return sThis;
    298 }
    299 }

    代码8-3-8 AndroidDebugBridge - createBridge

    第273行AndroidDebugBridge的构造函数做的事情就是实例化AndroidDebugBridge,ADB真正启动起来是调用274行的start()这个成员方法:

    713   boolean start()

     714   {

     715     if ((this.mAdbOsLocation != null) &&

    (sAdbServerPort != 0) &&

    ((!this.mVersionCheck) || (!startAdb()))) {

     716       return false;

     717     }

     718

     719     this.mStarted = true;

     720

     721

     722     this.mDeviceMonitor = new DeviceMonitor(this);

     723     this.mDeviceMonitor.start();

     724

     725     return true;

     726   }

    代码8-3-9 AndroidDebugBridge - start

    这里做了几个很重要的事情:

    1. 715行startAdb:开启AndroidDebugBridge
    2. 722-723行: 初始化android设备监控并启动DeviceMonitor设备监控线程。

    这一小节我们先看第一个startAdb,看它是如何把AndroidDebugBridge给开启起来的,第2点我们将会在下一小节描述。

    943   synchronized boolean startAdb()

     944   {

     945     if (this.mAdbOsLocation == null) {

     946       Log.e("adb", "Cannot start adb when AndroidDebugBridge is created without the location of adb.");

     947

     948       return false;

     949     }

     950

     951     if (sAdbServerPort == 0) {

     952       Log.w("adb", "ADB server port for starting AndroidDebugBridge is not set.");

     953       return false;

     954     }

     955

     956

     957     int status = -1;

     958

     959     String[] command = getAdbLaunchCommand("start-server");

     960     String commandString = Joiner.on(',').join(command);

     961     try {

     962       Log.d("ddms", String.format("Launching '%1$s' to ensure ADB is running.", new Object[] { commandString }));

     963       ProcessBuilder processBuilder = new ProcessBuilder(command);

     964       if (DdmPreferences.getUseAdbHost()) {

     965         String adbHostValue = DdmPreferences.getAdbHostValue();

     966         if ((adbHostValue != null) && (!adbHostValue.isEmpty()))

     967         {

     968           Map<String, String> env = processBuilder.environment();

     969           env.put("ADBHOST", adbHostValue);

     970         }

     971       }

     972       Process proc = processBuilder.start();

     973     

     974       ArrayList<String> errorOutput = new ArrayList();

     975       ArrayList<String> stdOutput = new ArrayList();

     976       status = grabProcessOutput(proc, errorOutput, stdOutput, false);

     977     } catch (IOException ioe) {

     978       Log.e("ddms", "Unable to run 'adb': " + ioe.getMessage());

     979     }

     980     catch (InterruptedException ie) {

     981       Log.e("ddms", "Unable to run 'adb': " + ie.getMessage());

     982     }

     983   

     984

     985     if (status != 0) {

     986       Log.e("ddms", String.format("'%1$s' failed -- run manually if necessary", new Object[] { commandString }));

     987     

     988       return false;

     989     }

     990     Log.d("ddms", String.format("'%1$s' succeeded", new Object[] { commandString }));

     991     return true;

     992   }

    代码8-3-10 AndroidDebugBridge - startAdb

    这里所做的事情就是:

    • 准备好启动db server的command字串
    • 通过ProcessBuilder启动command字串指定的adb server
    • 错误处理

    command字串通过959行的getAdbLauncherCommand('start-server')来实现:

    994   private String[] getAdbLaunchCommand(String option)

     995   {

     996     List<String> command = new ArrayList(4);

     997     command.add(this.mAdbOsLocation);

     998     if (sAdbServerPort != 5037) {

     999       command.add("-P");

    1000       command.add(Integer.toString(sAdbServerPort));

    1001     }

    1002     command.add(option);

    1003     return (String[])command.toArray(new String[command.size()]);

    1004   }

    代码8-3-11  AndroidDebugBridge - getAdbLaunchCommand

    整个函数玩的就是字串组合,最后获得的字串就是”adb -P $port start-server”,也就是开启adb服务器的命令行字串了,最终把这个字串打散成字串数组返回。这里注意port默认值就是ADB服务器的默认监听端口5037。

    startAdb方法获得命令之后下一步就是直接调用java的ProcessBuilder构造函数来创建一个ADB服务器进程了。创建好后就可以通过972行的‘processBuilder.start()‘把这个进程启动起来。

    迄今为止AndroidDebugBridge启动函数start()所做事情的第一点“1. 启动AndroidDebugBridge"已经完成了,adb服务器进程已经运行起来了。

  • 相关阅读:
    【BZOJ4769】超级贞鱼 归并排序求逆序对
    [简明版] 有道云笔记Markdown指南
    在Pycharm中配置Github
    Linux学习笔记之Xshell配色方案定制
    前端学习笔记之ES6快速入门
    魔改有道云笔记
    Python爬虫学习笔记之Centos下安装配置Mongodb3.6
    Linux学习笔记之CentOS6.9 防火墙的关闭以及开启
    Web前端学习笔记之jQuery选择器
    Django学习笔记之Queryset详解
  • 原文地址:https://www.cnblogs.com/poptest/p/5086408.html
Copyright © 2020-2023  润新知