Android之Monkey源码分析(第一篇:环境与命令)

Monkey源码获取:https://android.googlesource.com/platform/development.git/ 

前言

    monkey,一个Android平台的命令行工具,对于你是不是既熟悉又陌生,我相信很多同学一定熟悉monkey的使用,多数都是copy命令行,哈哈,陌生的是你对它的原理可能完全不懂吧,monkey程序是如何实现的呢?让我们学习学习monkey的业务逻辑!

monkey源码下载地址:https://github.com/aosp-mirror/platform_development/tree/master/cmds/monkey

Google:https://android.googlesource.com/platform/development.git/+/refs/heads/master/cmds/monkey/src/com/android/commands/monkey

检查monkey命令的类型

adb shell type monkey
monkey is a tracked alias for /system/bin/monkey

    Android基于Linux内核,所以它也有内置的type命令【备注:type命令是一个可执行文件(程序),用于查看可执行文件的类型】, 当我们执行如下语句

adb shell type monkey

标准输出中则会出现这么一行:monkey is a tracked alias for /system/bin/monkey

这句话的意思是:monkey是/system/bin/monkey这个可执行文件的别称【备注:别称是类unix系统的下概念,大家可以私下去学习】,当我们输入adb shell monkey的时候,实际运行的程序为Android系统中的/system/bin/monkey这个可执行文件,接下来我们学习/system/bin/monkey这个文本文件的内容是什么呢?

/system/bin/monkey源码分析

# Script to start "monkey" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=$base/framework/monkey.jar
trap "" HUP
for a in "$@"; do
    echo "  bash arg:" $a
done
exec app_process $base/bin com.android.commands.monkey.Monkey "$@"

    这个代码量也不大,我就都贴上来了,下面听我慢慢道来!!! 

    /system/bin/monkey是monkey的可执行文件(程序),本身也是个文本文件(拥有字符编码的文本,就是文本文件),它是位于/system/bin目录下的一个shell脚本文件【备注:具备可执行权限的文本文件,遵守了bash规范,常称为shell脚本程序,简称shell脚本】

    接下来分析这个shell脚本文件的详细代码内容

备注:#开头的是shell脚本编程中的注释

1、创建全局变量base,用于存储目录名称

创建一个称为base的全局变量,变量值是字符串/system,存储的是一个字符串路径(备注:shell脚本只有一种数据类型:字符串)

2、导出环境变量值,用于记录monkey.jar文件的绝对路径

export命令用于导出环境变量CLASSPATH,该环境变量值是$base/framework/monkey.jar(备注:$字符是shell编程中的变量值替换字符,shell解释器会先执行变量值替换),这里是两个步骤

第一:shell脚本解释器先做变量值替换(就是将变量名替换为变量值)

第二:再做字符串拼接(备注:shell脚本的字符串拼接,仅需紧挨着,不用+号)

由于$base会被替换为/system,所以最终的CLASSPATH的变量值为/system/framework/monkey.jar

monkey.jar是monkey项目的字节码jar包,里面都是.class字节码文件,可见monkey程序是Java写的……(are you sure?难道不是dex?),这个CLASSPATH环境变量就是给Java虚拟机程序读取用的

3、捕获HUB信号,然后处理

trap命令用于捕获信号,然后处理,HUP:HUP表示中断信号,用户键入<Ctrl+X>时由终端驱动程序发送的信号,中间""表示捕获信号之后做的事情,这里表示捕获到HUP信号后什么也没有做!【备注:信号是Linux进程间通信的方式之一】

4、循环所有命令行参数,写入标准输出(屏幕)……

一行一个的打印命令行参数(以空格字符隔开),shell中for循环的语法,echo命令用于向屏幕中输出内容,$@可以获取到所有的命令行参数,我们给monkey命令传入的所有命令行参数,echo将接收到的所有命令行参数原样写入到标准输出

5、替换程序,可执行文件(程序)app_process开始运行

exec命令用于在当前shell进程中替换一个新的程序,这里会替换一个新的程序运行,这个程序就是app_process。此处最初为shell进程,接着shell进程执行的程序替换为app_process(当前的shell程序会被替换,改为执行app_process程序的代码逻辑),$bash/bin和com.android.commands.monkey.Monkey、还有"$@"解析出来的所有命令行参数,会拼接一个一个的命令行函数再传递给app_process程序(可执行文件)

app_process是一个可执行文件,由c++编写的程序,它会创建虚拟机实例,用来执行Java程序

执行Java程序时,会将所有命令行参数,传入Java程序的入口类

解析一下app_process是什么

    Android上的一个可执行文件(程序),由c++编写,它是zygote进程中实际运行的程序,在app_process程序中会创建虚拟机实例(Android平台中的ART虚拟机),由于app_process涉及内容多,该篇点到为止,后面会专门写一篇app_process程序的分析(这个卷了,c++不熟悉),这里暂时知道monkey程序的主要业务逻辑都是在monkey.jar包中的字节码文件中,app_process程序根据约定会读取CLASSPATH环境变量的值,由于CLASSPATH环境值指向的是CLASSPATH=$base/framework/monkey.jar,所以app_process程序会从monkey.jar文件中,查找作为命令行参数的com.android.commands.monkey.Monkey类,接着加载这个Monkey类到ART虚拟机中,开始执行Java程序了。

举个实际例子

adb shell monkey -p your.package.name -v 500

    我们在命令行中执行如上一行monkey命令(程序),共计传入4个命令行参数到monkey脚本中【备注:shell编程中的空白字符用于隔开每个单词作为命令行参数】

    以下是shell解释器执行完变量值替换后的monkey程序【备注:shell解释器背后会先做变量值替换,接着是命令行参数替换,最后才会执行命令】

# Script to start "monkey" on the device, which has a very rudimentary
# shell.
#
base=/system
export CLASSPATH=/system/framework/monkey.jar
trap "" HUP
for a in -p your.package.name -v 500; do
    echo "  bash arg:" $a
done
exec app_process $base/bin com.android.commands.monkey.Monkey -p your.package.name -v 500

总结

1、com.android.commands.monkey.Monkey,该参数表示此Java程序的入口类为Monkey,按照java程序的规范(标准),Monkey类的静态方法main()会执行,而Monkey类后面的所有命令行参数,比如上文中提及的传入的几个参数,会全部传递到Java程序中(app_process程序调用Java程序时执行的)

2、在我的第二篇文章中,我将分析Java程序Monkey类的静态方法main(),静态方法main()是monkey程序的入口,monkey的主线程流程(进程)将在此运行

3、Android平台的monkey程序,涉及到shell脚本程序(monkey)、c++程序(app_process)、java程序,主要的业务逻辑全部在Java程序中,佩服佩服,牛逼牛逼!!!!程序之间相互调用,简直太拽了…………

4、本人不会c++程序,有点遗憾啊,什么时候恶补一波啊,不然总觉得缺点什么!!!

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值