赞
踩
// Monkey的源码 public class Monkey { //程序入口 public static void main(String[] args) { Process.setArgV0("com.android.commands.monkey"); Logger.err.println("args: " + Arrays.toString(args)); // 1.调用run方法 int resultCode = (new Monkey()).run(args); System.exit(resultCode); } private int run(String[] args) { ... // 2.处理命令行选项 if (!processOptions()) { return -1; } // 3.加载包黑名单或白名单(如果指定)。 if (!loadPackageLists()) { return -1; } // 4.如果没有从外部传-s参数,随机因子默认为0,就会在此处初始化 if (mSeed == 0) { mSeed = System.currentTimeMillis() + System.identityHashCode(this); } // 5.检查所有系统接口是否都可用(检查ActivityManager,IWindowManager,IPackageManager) if (!getSystemInterfaces()) { return -3; } // 6.创建随机数生成器 mRandom = new Random(mSeed); // 7.根据不同的参数去初始化不同的事件源 if (mScriptFileNames != null && mScriptFileNames.size() == 1) { // script mode, ignore other options mEventSource = new MonkeySourceScript(mRandom, mScriptFileNames.get(0), mThrottle, mRandomizeThrottle, mProfileWaitTime, mDeviceSleepTime); mEventSource.setVerbose(mVerbose); mCountEvents = false; } else if (mScriptFileNames != null && mScriptFileNames.size() > 1) { ... mEventSource = new MonkeySourceRandomScript(mScriptFileNames, mThrottle, mRandomizeThrottle, mRandom, mProfileWaitTime, mDeviceSleepTime, mRandomizeScript); } else if (mServerPort != -1) {try { ... mEventSource = new MonkeySourceNetwork(mServerPort); } else { // 默认随机源 if (mVerbose >= 2) { // check seeding performance Logger.out.println("// Seeded: " + mSeed); } mEventSource = new MonkeySourceRandom(mRandom, mMainApps, mThrottle, mRandomizeThrottle, mPermissionTargetSystem); mEventSource.setVerbose(mVerbose); // 8.设置已设置的比例因子 for (int i = 0; i < MonkeySourceRandom.FACTORZ_COUNT; i++) { if (mFactors[i] <= 0.0f) { ((MonkeySourceRandom) mEventSource).setFactors(i, mFactors[i]); } } // 在随机模式下,从activity开始 ((MonkeySourceRandom) mEventSource).generateActivity(); } // 9.验证源发生器 if (!mEventSource.validate()) { return -5; } ... mNetworkMonitor.start(); // 10.循环执行monkey事件 int crashedAtCycle = runMonkeyCycles(); mNetworkMonitor.stop(); } } //循环monkey事件 private int runMonkeyCycles() { ... // 循环执行monkey事件(当没有出现系统报错或者当前执行事件数没有大于设置的事件数时) while (!systemCrashed && cycleCounter < mCount) { 11.从步骤7初始化的mEventSource对象中取出事件 MonkeyEvent ev = mEventSource.getNextEvent(); if (ev != null) { 12.对事件进行注入执行 int injectCode = ev.injectEvent(mWm, mAm, mVerbose); ... } ... } }
主要验证用户设置的各种事件数比例符不符合要求,然后再通过用户设置的事件数比例和系统的事件数比例进行调整。
public class Monkey { private int run(String[] args) { // 1.验证源发生器 if (!mEventSource.validate()) { return -5; } // 设置已设置的比例因子(有传参过来的就设置,没有传参的默认为0) for (int i = 0; i < MonkeySourceRandom.FACTORZ_COUNT; i++) { if (mFactors[i] <= 0.0f) { ((MonkeySourceRandom) mEventSource).setFactors(i, mFactors[i]); } } } } public class MonkeySourceRandom implements MonkeyEventSource { public boolean validate() { boolean ret = true; ... //调用adjustEventFactors方法 return ret & adjustEventFactors(); } //调整百分比(在应用用户值之后) private boolean adjustEventFactors() { // go through all values and compute totals for user & default values // 检查所有值并计算用户和默认值的总数 float userSum = 0.0f; float defaultSum = 0.0f; int defaultCount = 0; for (int i = 0; i < FACTORZ_COUNT; ++i) { // 2.用户设置为零或负值 if (mFactors[i] <= 0.0f) { // 这个地方为什么是减等于,因为初始化的时候设置的是负数值(Monkey类的processOptions()方法中初始化的时候可以看到) userSum -= mFactors[i]; } else { defaultSum += mFactors[i]; ++defaultCount; } } // 3.如果用户请求是> 100%,直接返回false报出错误 if (userSum > 100.0f) { Logger.err.println("** Event weights > 100%"); return false; } // 4.如果用户指定了所有的权重,那么它们需要是100% if (defaultCount == 0 && (userSum < 99.9f || userSum > 100.1f)) { Logger.err.println("** Event weights != 100%"); return false; } // 5.计算必要的调整 float defaultsTarget = (100.0f - userSum); float defaultsAdjustment = defaultsTarget / defaultSum; // 6.通过调整默认值或将用户值翻转回>0来修复所有值 for (int i = 0; i < FACTORZ_COUNT; ++i) { if (mFactors[i] <= 0.0f) { // user values are zero or negative mFactors[i] = -mFactors[i]; } else { mFactors[i] *= defaultsAdjustment; } } if (mVerbose > 0) { Logger.out.println("// Event percentages:"); for (int i = 0; i < FACTORZ_COUNT; ++i) { Logger.out.println("// " + i + ": " + mFactors[i] + "%"); } } // 7.最后,规范化并转换为运行求和 float sum = 0.0f; for (int i = 0; i < FACTORZ_COUNT; ++i) { sum += mFactors[i] / 100.0f; mFactors[i] = sum; } return true; } }
public class Monkey { //循环monkey事件 private int runMonkeyCycles() { ... // 循环执行monkey事件(当没有出现系统报错或者当前执行事件数没有大于设置的事件数时) while (!systemCrashed && cycleCounter < mCount) { 1.从mEventSource对象中取出事件 MonkeyEvent ev = mEventSource.getNextEvent(); if (ev != null) { 对事件进行注入执行 int injectCode = ev.injectEvent(mWm, mAm, mVerbose); ... } ... } public class MonkeySourceRandom implements MonkeyEventSource { public MonkeyEvent getNextEvent() { // 2.如果队列为空,则首先生成事件 if (mQ.isEmpty()) { generateEvents(); } mEventCount++; // 5.获取最前面的值,移除出队列 MonkeyEvent e = mQ.getFirst(); mQ.removeFirst(); return e; } //3.生成随机事件 private void generateEvents() { float cls = mRandom.nextFloat(); int lastKey = 0; // 根据随机数生成器生成的随机数 匹配在此区间内的事件 if (cls < mFactors[FACTOR_TOUCH]) { generatePointerEvent(mRandom, GESTURE_TAP); return; } else if (cls < mFactors[FACTOR_MOTION]) { generatePointerEvent(mRandom, GESTURE_DRAG); return; } else if (cls < mFactors[FACTOR_PINCHZOOM]) { generatePointerEvent(mRandom, GESTURE_PINCH_OR_ZOOM); return; } else if (cls < mFactors[FACTOR_TRACKBALL]) { generateTrackballEvent(mRandom); return; } else if (cls < mFactors[FACTOR_ROTATION]) { generateRotationEvent(mRandom); return; } else if (cls < mFactors[FACTOR_PERMISSION]) { mQ.add(mPermissionUtil.generateRandomPermissionEvent(mRandom)); return; } ... //4.把生成的事情添加到MonkeyEventQueue对象中 mQ.addLast(e); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。