上回说到,调用了Java端的notifyANR()方法,那么这个方法是在哪被执行的呢?
2.
frameworks/base/services/core/java/com/android/server/input/InputManagerService.java
2.1
notifyANR()方法就是在InputManagerService.java中被执行的,来看代码
// Native callback.
private long notifyANR(IBinder token, String reason) {
return mWindowManagerCallbacks.notifyANR(token, reason);
}
/Q_Mainline/frameworks/base/services/core/java/com/android/server/wm/InputManagerCallback.java
final class InputManagerCallback implements InputManagerService.WindowManagerCallbacks {所以再看InputManagerCallback中的notifyANR()
2.2
notifyANR() :通过判断appWindowToken,appWindowToken.appToken和windowState,去调用不同的方法keyDispatchingTimedOut()和inputDispatchingTimedOut()
再看inputDispatchingTimedOut():调用链为
两个方法最后都调用了appNotResponding()方法,来处理app无响应时的情况
public long notifyANR(IBinder token, String reason) {
if (appWindowToken != null && appWindowToken.appToken != null) {
// Notify the activity manager about the timeout and let it decide whether
// to abort dispatching or keep waiting.
final boolean abort = appWindowToken.keyDispatchingTimedOut(reason,
(windowState != null) ? windowState.mSession.mPid : -1);
} else if (windowState != null) {
// Notify the activity manager about the timeout and let it decide whether
// to abort dispatching or keep waiting.
long timeout = mService.mAmInternal.inputDispatchingTimedOut(
windowState.mSession.mPid, aboveSystem, reason);
}
return 0; // abort dispatching
}2.3
proc.appNotResponding()最后又调用了ProcessRecord.java中的appNotRespondingImpl(),然后继续调用AMS中的dumpStackTraces方法
void appNotRespondingImpl(String activityShortComponentName, ApplicationInfo aInfo,
String parentShortComponentName, WindowProcessController parentProcess,
boolean aboveSystem, String annotation) {
// Original code
// For background ANRs, don't pass the ProcessCpuTracker to
// avoid spending 1/2 second collecting stats to rank lastPids.
tracesFile = ActivityManagerService.dumpStackTraces(firstPids,
(isSilentAnr()) ? null : processCpuTracker, (isSilentAnr()) ? null : lastPids,
nativePids);
}
2.4
public static final String ANR_TRACE_DIR = "/data/anr";
public static File dumpStackTraces(ArrayList firstPids,
ProcessCpuTracker processCpuTracker, SparseArray lastPids,
ArrayList nativePids) {
ArrayList extraPids = null;
//ANR_TRACE_DIR = "/data/anr"
final File tracesDir = new File(ANR_TRACE_DIR);
File tracesFile = createAnrDumpFile(tracesDir);
if (tracesFile == null) {
return null;
}
//tracesFile..getAbsolutePath() = "/data/anr/anr_Date"
dumpStackTraces(tracesFile.getAbsolutePath(), firstPids, nativePids, extraPids);
return tracesFile;
}
private static synchronized File createAnrDumpFile(File tracesDir) {
if (sAnrFileDateFormat == null) {
sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
}
final String formattedDate = sAnrFileDateFormat.format(new Date());
final File anrFile = new File(tracesDir, "anr_" + formattedDate);
try {
if (anrFile.createNewFile()) {
FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
return anrFile;
} else {
Slog.w(TAG, "Unable to create ANR dump file: createNewFile failed");
}
} catch (IOException ioe) {
Slog.w(TAG, "Exception creating ANR dump file:", ioe);
}
return null;
}2.5
for循环遍历了firstPids集合,对每个pid都调用dumpJavaTracesTombstoned()方法
public static void dumpStackTraces(String tracesFile, ArrayList firstPids,
ArrayList nativePids, ArrayList extraPids) {
// First collect all of the stacks of the most important pids.
if (firstPids != null) {
int num = firstPids.size();
for (int i = 0; i < num; i++) {
Slog.i(TAG, "Collecting stacks for pid " + firstPids.get(i));
final long timeTaken = dumpJavaTracesTombstoned(firstPids.get(i), tracesFile, remainingTime);
}
}
}2.6
参数pid = pid , fileName = "/data/anr/anr_Date",timeoutMs = 20 * 1000;
private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
final long timeStart = SystemClock.elapsedRealtime();
boolean javaSuccess = Debug.dumpJavaBacktraceToFileTimeout(pid, fileName,
(int) (timeoutMs / 1000));
}2.7
Debug.dumpJavaBacktraceToFileTimeout():是一个native方法,通过jni,实现在c++中,方法名为android_os_Debug_dumpJavaBacktraceToFileTimeout
public static native boolean dumpJavaBacktraceToFileTimeout(int pid, String file,
int timeoutSecs);
/*
* JNI registration.
*/
static const JNINativeMethod gMethods[] = {
{ "dumpJavaBacktraceToFileTimeout", "(ILjava/lang/String;I)Z",
(void*)android_os_Debug_dumpJavaBacktraceToFileTimeout },
}; 待续。。。。。