承接上文,在 【Android Monkey源码解析三】- 运行解析 中,有介绍到run方法中的getSystemInterfaces方法是获取所有系统接口对象的。其中异常捕获和页面控制就是通过ActivityManager的setActivityController方法来实现的,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 private boolean getSystemInterfaces () { mAm = ActivityManager.getService(); if (mAm == null ) { Logger.err.println("** Error: Unable to connect to activity manager; is the system " + "running?" ); return false ; } ... try { mAm.setActivityController(new ActivityController (), true ); mNetworkMonitor.register(mAm); } catch (RemoteException e) { Logger.err.println("** Failed talking with activity manager!" ); return false ; } return true ; }
这里,创建了一个新的ActivityController对象,设置给了ActivityManager的setActivityController的第一个参数。下面看下ActivityController的实现,源码地址:https://android.googlesource.com/platform/development/+/refs/heads/android12-release/cmds/monkey/src/com/android/commands/monkey/Monkey.java#265 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 private class ActivityController extends IActivityController .Stub { public boolean activityStarting (Intent intent, String pkg) { final boolean allow = isActivityStartingAllowed(intent, pkg); if (mVerbose > 0 ) { StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); Logger.out.println(" // " + (allow ? "Allowing" : "Rejecting" ) + " start of " + intent + " in package " + pkg); StrictMode.setThreadPolicy(savedPolicy); } currentPackage = pkg; currentIntent = intent; return allow; } private boolean isActivityStartingAllowed (Intent intent, String pkg) { if (MonkeyUtils.getPackageFilter().checkEnteringPackage(pkg)) { return true ; } if (DEBUG_ALLOW_ANY_STARTS != 0 ) { return true ; } final Set<String> categories = intent.getCategories(); if (intent.getAction() == Intent.ACTION_MAIN && categories != null && categories.contains(Intent.CATEGORY_HOME)) { try { final ResolveInfo resolveInfo = mPm.resolveIntent(intent, intent.getType(), 0 , ActivityManager.getCurrentUser()); final String launcherPackage = resolveInfo.activityInfo.packageName; if (pkg.equals(launcherPackage)) { return true ; } } catch (RemoteException e) { Logger.err.println("** Failed talking with package manager!" ); return false ; } } return false ; } public boolean activityResuming (String pkg) { StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); Logger.out.println(" // activityResuming(" + pkg + ")" ); boolean allow = MonkeyUtils.getPackageFilter().checkEnteringPackage(pkg) || (DEBUG_ALLOW_ANY_RESTARTS != 0 ); if (!allow) { if (mVerbose > 0 ) { Logger.out.println(" // " + (allow ? "Allowing" : "Rejecting" ) + " resume of package " + pkg); } } currentPackage = pkg; StrictMode.setThreadPolicy(savedPolicy); return allow; } public boolean appCrashed (String processName, int pid, String shortMsg, String longMsg, long timeMillis, String stackTrace) { StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); Logger.err.println("// CRASH: " + processName + " (pid " + pid + ")" ); Logger.err.println("// Short Msg: " + shortMsg); Logger.err.println("// Long Msg: " + longMsg); Logger.err.println("// Build Label: " + Build.FINGERPRINT); Logger.err.println("// Build Changelist: " + Build.VERSION.INCREMENTAL); Logger.err.println("// Build Time: " + Build.TIME); Logger.err.println("// " + stackTrace.replace("\n" , "\n// " )); StrictMode.setThreadPolicy(savedPolicy); if (mMatchDescription == null || shortMsg.contains(mMatchDescription) || longMsg.contains(mMatchDescription) || stackTrace.contains(mMatchDescription)) { if (!mIgnoreCrashes || mRequestBugreport) { synchronized (Monkey.this ) { if (!mIgnoreCrashes) { mAbort = true ; } if (mRequestBugreport){ mRequestAppCrashBugreport = true ; mReportProcessName = processName; } } return !mKillProcessAfterError; } } return false ; } public int appEarlyNotResponding (String processName, int pid, String annotation) { return 0 ; } public int appNotResponding (String processName, int pid, String processStats) { StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); Logger.err.println("// NOT RESPONDING: " + processName + " (pid " + pid + ")" ); Logger.err.println(processStats); StrictMode.setThreadPolicy(savedPolicy); if (mMatchDescription == null || processStats.contains(mMatchDescription)) { synchronized (Monkey.this ) { mRequestAnrTraces = true ; mRequestDumpsysMemInfo = true ; mRequestProcRank = true ; if (mRequestBugreport) { mRequestAnrBugreport = true ; mReportProcessName = processName; } } if (!mIgnoreTimeouts) { synchronized (Monkey.this ) { mAbort = true ; } } } return (mKillProcessAfterError) ? -1 : 1 ; } public int systemNotResponding (String message) { StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); Logger.err.println("// WATCHDOG: " + message); StrictMode.setThreadPolicy(savedPolicy); synchronized (Monkey.this ) { if (mMatchDescription == null || message.contains(mMatchDescription)) { if (!mIgnoreCrashes) { mAbort = true ; } if (mRequestBugreport) { mRequestWatchdogBugreport = true ; } } mWatchdogWaiting = true ; } synchronized (Monkey.this ) { while (mWatchdogWaiting) { try { Monkey.this .wait(); } catch (InterruptedException e) { } } } return (mKillProcessAfterError) ? -1 : 1 ; } }
本篇主要介绍了ActivityController的异常捕获/页面控制处理,下面会介绍在出现应用崩溃(appCrashed),应用无响应(appNotResponding),系统无响应时的处理分析(systemNotResponding)。
本文链接: http://longzhiye.top/2025/10/07/2025-10-07/