老李推荐:第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
这里做了几个很重要的事情:
- 715行startAdb:开启AndroidDebugBridge
- 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服务器进程已经运行起来了。
老李推荐:第8章3节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-启动AndroidDebugBridge 3的更多相关文章
- 老李推荐:第5章7节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 循环获取并执行事件 - runMonkeyCycles
老李推荐:第5章7节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 循环获取并执行事件 - runMonkeyCycles poptest是国内唯一一家培养测试开 ...
- 老李推荐:第5章6节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 初始化事件源
老李推荐:第5章6节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 初始化事件源 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试 ...
- 老李推荐:第5章3节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 启动脚本
老李推荐:第5章3节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 启动脚本 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性 ...
- 老李推荐:第5章5节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 获取系统服务引用
老李推荐:第5章5节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 获取系统服务引用 上一节我们描述了monkey的命令处理入口函数run是如何调用optionP ...
- 老李推荐:第5章2节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 启动流程概览
老李推荐:第5章2节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 启动流程概览 每个应用都会有一个入口方法来供操作系统调用执行,Monkey这个应用的入口方法就 ...
- 老李推荐:第5章1节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 官方简介
老李推荐:第5章1节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 官方简介 在MonkeyRunner的框架中,Monkey是作为一个服务来接受来自Monkey ...
- 第5章1节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 官方简介(原创)
天地会珠海分舵注:本来这一系列是准备出一本书的,详情请见早前博文“寻求合作伙伴编写<深入理解 MonkeyRunner>书籍“.但因为诸多原因,没有如愿.所以这里把草稿分享出来,所以错误在 ...
- 老李推荐:第14章9节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-遍历控件树查找控件
老李推荐:第14章9节<MonkeyRunner源码剖析> HierarchyViewer实现原理-遍历控件树查找控件 poptest是国内唯一一家培养测试开发工程师的培训机构,以学员 ...
- 老李推荐:第14章5节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-查询ViewServer运行状态
老李推荐:第14章5节<MonkeyRunner源码剖析> HierarchyViewer实现原理-装备ViewServer-查询ViewServer运行状态 poptest是国内唯一 ...
- 老李推荐:第14章6节《MonkeyRunner源码剖析》 HierarchyViewer实现原理-装备ViewServer-启动ViewServer
老李推荐:第14章6节<MonkeyRunner源码剖析> HierarchyViewer实现原理-装备ViewServer-启动ViewServer poptest是国内唯一一家培养 ...
随机推荐
- JAVA设计模式:单例设计
1.单例设计Singleton的引出 单例设计,从名字上首先可以看出单---即只有一个,例---只的是实例化对象:那么单例也就是说一个类,只产生了一个实例化对象.但是我们都知道,一个类要产生实例化对象 ...
- BZOJ 3924: [Zjoi2015]幻想乡战略游戏(动态点分治)
这种动态点分治嘛,GDKOI时听打到了,也有同学讲到了,所以印象比较深刻也就想出来了,然后就在实现方面卡了好久= = 不得不说CLJ说得真的太简单了,实现方面根本没提. 首先我们可以先用树分治构建出这 ...
- netflix ribbon概述
LB方案分类 目前主流的LB方案可分成两类:一种是集中式LB, 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5, 也可以是软件,如nginx), 由该设施负责把访问请求通过某种策略 ...
- 一个初学所了解的jquery事件
在jquery中,事件总体分为两大类:简单是件和复合事件今天我们只来学习一下简单事件 绑定事件和事件处理函数的语法格式(DOM 对象.事件名=函数:) 简单事件分为: 1.window事件 所谓win ...
- 读书笔记 effective c++ Item 21 当你必须返回一个对象的时候,不要尝试返回引用
1. 问题的提出:要求函数返回对象时,可以返回引用么? 一旦程序员理解了按值传递有可能存在效率问题之后(Item 20),许多人都成了十字军战士,决心清除所有隐藏的按值传递所引起的开销.对纯净的按引用 ...
- [Hadoop] - Cannot run program "cmake"
在编译hadoop的过程中,遇到缺少cmake命令的异常,异常信息为:Cannot run program "cmake" (in directory "/opt/wor ...
- Laravel事件Event
适用场景:记录文章浏览量 php artisan make:event 事件名 示例: php artisan make:event MyEvent Laravel目录\app\Events已经生成M ...
- Vue2.0音乐播放器
学习了几周的vuejs,学习的过程中做了一个音乐播放器WebApp (顺便听听音乐~) ,过程中也有借鉴过别人做的,感觉受益匪浅 链接 项目在线地址 : 音乐播放器 github : https:// ...
- iOS集成友盟推送
之前有写过利用Python自己写一个推送服务器, 今天说下如果集成友盟的推送服务 在这之前我们需要做一些准备动作 #1. 注册一个App ID #2. Enable Push Notification ...
- springMVC中文乱码问题解决
1:表单提交controller获得中文参数后乱码解决方案 注意: jsp页面编码设置为UTF-8 form表单提交方式为必须为post,get方式下面spring编码过滤器不起效果 <%@ ...