java application的異常處理流程
阿新 • • 發佈:2019-01-29
1. java application 異常發生後的程式碼流程:
程式碼流程是函式檔案
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java的函式UncaughtHandler控制的:
/**
* Use this to log a message when a thread exits due to an uncaught
* exception. The framework catches these for the main threads, so
* this should only matter for threads created by applications.
*/
private static class UncaughtHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
try {
// Don't re-enter -- avoid infinite loops if crash-reporting crashes.
if (mCrashing) return;
mCrashing = true;
if (mApplicationObject == null) {
Clog_e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
} else {
StringBuilder message = new StringBuilder();
message.append("FATAL EXCEPTION: ").append(t.getName()).append("\n");
final String processName = ActivityThread.currentProcessName();
if (processName != null) {
message.append("Process: ").append(processName).append(", ");
}
message.append("PID: ").append(Process.myPid());
Clog_e(TAG, message.toString(), e);
}
// Bring up crash dialog, wait for it to be dismissed
ActivityManagerNative.getDefault().handleApplicationCrash(
mApplicationObject, new ApplicationErrorReport.CrashInfo(e));
} catch (Throwable t2) {
try {
Clog_e(TAG, "Error reporting crash", t2);
} catch (Throwable t3) {
// Even Clog_e() fails! Oh well.
}
} finally {
// Try everything to make sure this process goes away.
Process.killProcess(Process.myPid());
System.exit(10);
}
}
}
2. application crash後輸出什麼樣的log:
message.append("FATAL EXCEPTION: ").append(t.getName()).append("\n");
message.append("Process: ").append(processName).append(", ");
message.append("PID: ").append(Process.myPid());
5395 5395 E AndroidRuntime: FATAL EXCEPTION: main
5395 5395 E AndroidRuntime: Process: com.example.ritter.fcandanr, PID: 5395
下面的呼叫棧是哪裡輸出的?
private static int Clog_e(String tag, String msg, Throwable tr) {
return Log.println_native(Log.LOG_ID_CRASH, Log.ERROR, tag,
msg + '\n' + Log.getStackTraceString(tr));
}
函式Clog_e中呼叫了getStackTraceString
5395 5395 E AndroidRuntime: java.lang.IllegalStateException: Could not execute method for android:onClick
5395 5395 E AndroidRuntime: at android.view.View$DeclaredOnClickListener.onClick(View.java:4461)
5395 5395 E AndroidRuntime: at android.view.View.performClick(View.java:5207)
5395 5395 E AndroidRuntime: at android.view.View$PerformClick.run(View.java:21177)
5395 5395 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
5395 5395 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
5395 5395 E AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
5395 5395 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5485)
5395 5395 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
5395 5395 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
5395 5395 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
5395 5395 E AndroidRuntime: Caused by: java.lang.reflect.InvocationTargetException
5395 5395 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
5395 5395 E AndroidRuntime: at android.view.View$DeclaredOnClickListener.onClick(View.java:4456)
5395 5395 E AndroidRuntime: ... 9 more
5395 5395 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference
E AndroidRuntime: at com.example.ritter.fcandanr.MainActivity.onClickFC(MainActivity.java:75)
5395 5395 E AndroidRuntime: ... 11 more
3. 除了輸出異常log外:還呼叫了:handleApplicationCrash
/**
* Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
* The application process will exit immediately after this call returns.
* @param app object of the crashing app, null for the system server
* @param crashInfo describing the exception
*/
public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
ProcessRecord r = findAppProcess(app, "Crash");
final String processName = app == null ? "system_server"
: (r == null ? "unknown" : r.processName);
handleApplicationCrashInner("crash", r, processName, crashInfo);
}
/* Native crash reporting uses this inner version because it needs to be somewhat
* decoupled from the AM-managed cleanup lifecycle
*/
void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
ApplicationErrorReport.CrashInfo crashInfo) {
EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
UserHandle.getUserId(Binder.getCallingUid()), processName,
r == null ? -1 : r.info.flags,
crashInfo.exceptionClassName,
crashInfo.exceptionMessage,
crashInfo.throwFileName,
crashInfo.throwLineNumber);
addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
crashApplication(r, crashInfo);
}
3.1 event log: AM_CRASH的輸出:
EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
UserHandle.getUserId(Binder.getCallingUid()), processName,
r == null ? -1 : r.info.flags,
crashInfo.exceptionClassName,
crashInfo.exceptionMessage,
crashInfo.throwFileName,
crashInfo.throwLineNumber);
am_crash: [5395,0,com.example.ritter.fcandanr,948485702,java.lang.NullPointerException,Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference,MainActivity.java,75]
am_crash: [
5395,
0,
com.example.ritter.fcandanr,
948485702,
java.lang.NullPointerException,
Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference,
MainActivity.java,
75]
4 addErrorToDropBox
呼叫dropbox服務儲存一些資訊到dropbox路徑
/**
* Write a description of an error (crash, WTF, ANR) to the drop box.
* @param eventType to include in the drop box tag ("crash", "wtf", etc.)
* @param process which caused the error, null means the system server
* @param activity which triggered the error, null if unknown
* @param parent activity related to the error, null if unknown
* @param subject line related to the error, null if absent
* @param report in long form describing the error, null if absent
* @param logFile to include in the report, null if none
* @param crashInfo giving an application stack trace, null if absent
*/
public void addErrorToDropBox(String eventType,
ProcessRecord process, String processName, ActivityRecord activity,
ActivityRecord parent, String subject,
final String report, final File logFile,
final ApplicationErrorReport.CrashInfo crashInfo) {
// NOTE -- this must never acquire the ActivityManagerService lock,
// otherwise the watchdog may be prevented from resetting the system.
final String dropboxTag = processClass(process) + "_" + eventType;
final DropBoxManager dbox = (DropBoxManager)
mContext.getSystemService(Context.DROPBOX_SERVICE);
// Exit early if the dropbox isn't configured to accept this report type.
if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
final StringBuilder sb = new StringBuilder(1024);
appendDropBoxProcessHeaders(process, processName, sb);
if (activity != null) {
sb.append("Activity: ").append(activity.shortComponentName).append("\n");
}
if (parent != null && parent.app != null && parent.app.pid != process.pid) {
sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
}
if (parent != null && parent != activity) {
sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
}
if (subject != null) {
sb.append("Subject: ").append(subject).append("\n");
}
sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
if (Debug.isDebuggerConnected()) {
sb.append("Debugger: Connected\n");
}
sb.append("\n");
// Do the rest in a worker thread to avoid blocking the caller on I/O
// (After this point, we shouldn't access AMS internal data structures.)
Thread worker = new Thread("Error dump: " + dropboxTag) {
@Override
public void run() {
if (report != null) {
sb.append(report);
}
if (logFile != null) {
try {
sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
"\n\n[[TRUNCATED]]"));
} catch (IOException e) {
Slog.e(TAG, "Error reading " + logFile, e);
}
}
if (crashInfo != null && crashInfo.stackTrace != null) {
sb.append(crashInfo.stackTrace);
}
String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
if (lines > 0) {
sb.append("\n");
// Merge several logcat streams, and take the last N lines
InputStreamReader input = null;
try {
java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
"-v", "time", "-b", "events", "-b", "system", "-b", "main",
"-b", "crash",
"-t", String.valueOf(lines)).redirectErrorStream(true).start();
try { logcat.getOutputStream().close(); } catch (IOException e) {}
try { logcat.getErrorStream().close(); } catch (IOException e) {}
input = new InputStreamReader(logcat.getInputStream());
int num;
char[] buf = new char[8192];
while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
} catch (IOException e) {
Slog.e(TAG, "Error running logcat", e);
} finally {
if (input != null) try { input.close(); } catch (IOException e) {}
}
}
dbox.addText(dropboxTag, sb.toString());
}
};
if (process == null) {
// If process is null, we are being called from some internal code
// and may be about to die -- run this synchronously.
worker.run();
} else {
worker.start();
}
}
4.1 dropbox中儲存什麼樣的檔名
當前的檔名是 [email protected]
dropbox中的檔名由dropboxTag決定:
dropboxTag = processClass(process):
private static String processClass(ProcessRecord process) {
if (process == null || process.pid == MY_PID) {
return "system_server";
} else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
return "system_app";
} else {
return "data_app";
}
}
4.2 dropbox中儲存的檔案內容是:
rocess: com.example.ritter.fcandanr
Flags: 0x38a8be46
Package: com.example.ritter.fcandanr v1 (1.0)
Build: Xiaomi/gemini/gemini:6.0.1/MXB48T/1.1.1:user/test-keys
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.view.View$DeclaredOnClickListener.onClick(View.java:4461)
at android.view.View.performClick(View.java:5207)
at android.view.View$PerformClick.run(View.java:21177)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5485)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4456)
... 9 more
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference
at com.example.ritter.fcandanr.MainActivity.onClickFC(MainActivity.java:75)
... 11 more
4.3 dropbox中也是可以儲存當前的logcat
但是受setting控制:
String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
5. 彈出的對話方塊crashApplication(r, crashInfo);
/**
* Bring up the "unexpected error" dialog box for a crashing app.
* Deal with edge cases (intercepts from instrumented applications,
* ActivityController, error intent receivers, that sort of thing).
* @param r the application crashing
* @param crashInfo describing the failure
*/
private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Message msg = Message.obtain();
msg.what = SHOW_ERROR_MSG;
HashMap data = new HashMap();
data.put("result", result);
data.put("app", r);
// MIUI ADD:
data.put("crash", crashInfo);
msg.obj = data;
mUiHandler.sendMessage(msg);
Binder.restoreCallingIdentity(origId);
}
6. system_server的異常也是按上面的流程處理的
system_server的異常也是會彈出介面?會導致framework 層重啟?
程式碼流程是函式檔案
frameworks/base/core/java/com/android/internal/os/RuntimeInit.java的函式UncaughtHandler控制的:
/**
* Use this to log a message when a thread exits due to an uncaught
* exception. The framework catches these for the main threads, so
* this should only matter for threads created by applications.
*/
private static class UncaughtHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
try {
// Don't re-enter -- avoid infinite loops if crash-reporting crashes.
if (mCrashing) return;
mCrashing = true;
if (mApplicationObject == null) {
Clog_e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
} else {
StringBuilder message = new StringBuilder();
message.append("FATAL EXCEPTION: ").append(t.getName()).append("\n");
final String processName = ActivityThread.currentProcessName();
if (processName != null) {
message.append("Process: ").append(processName).append(", ");
}
message.append("PID: ").append(Process.myPid());
Clog_e(TAG, message.toString(), e);
}
// Bring up crash dialog, wait for it to be dismissed
ActivityManagerNative.getDefault().handleApplicationCrash(
mApplicationObject, new ApplicationErrorReport.CrashInfo(e));
} catch (Throwable t2) {
try {
Clog_e(TAG, "Error reporting crash", t2);
} catch (Throwable t3) {
// Even Clog_e() fails! Oh well.
}
} finally {
// Try everything to make sure this process goes away.
Process.killProcess(Process.myPid());
System.exit(10);
}
}
}
2. application crash後輸出什麼樣的log:
message.append("FATAL EXCEPTION: ").append(t.getName()).append("\n");
message.append("Process: ").append(processName).append(", ");
message.append("PID: ").append(Process.myPid());
5395 5395 E AndroidRuntime: FATAL EXCEPTION: main
5395 5395 E AndroidRuntime: Process: com.example.ritter.fcandanr, PID: 5395
下面的呼叫棧是哪裡輸出的?
private static int Clog_e(String tag, String msg, Throwable tr) {
return Log.println_native(Log.LOG_ID_CRASH, Log.ERROR, tag,
msg + '\n' + Log.getStackTraceString(tr));
}
函式Clog_e中呼叫了getStackTraceString
5395 5395 E AndroidRuntime: java.lang.IllegalStateException: Could not execute method for android:onClick
5395 5395 E AndroidRuntime: at android.view.View$DeclaredOnClickListener.onClick(View.java:4461)
5395 5395 E AndroidRuntime: at android.view.View.performClick(View.java:5207)
5395 5395 E AndroidRuntime: at android.view.View$PerformClick.run(View.java:21177)
5395 5395 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739)
5395 5395 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95)
5395 5395 E AndroidRuntime: at android.os.Looper.loop(Looper.java:148)
5395 5395 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5485)
5395 5395 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
5395 5395 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
5395 5395 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
5395 5395 E AndroidRuntime: Caused by: java.lang.reflect.InvocationTargetException
5395 5395 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
5395 5395 E AndroidRuntime: at android.view.View$DeclaredOnClickListener.onClick(View.java:4456)
5395 5395 E AndroidRuntime: ... 9 more
5395 5395 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference
E AndroidRuntime: at com.example.ritter.fcandanr.MainActivity.onClickFC(MainActivity.java:75)
5395 5395 E AndroidRuntime: ... 11 more
3. 除了輸出異常log外:還呼叫了:handleApplicationCrash
/**
* Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
* The application process will exit immediately after this call returns.
* @param app object of the crashing app, null for the system server
* @param crashInfo describing the exception
*/
public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
ProcessRecord r = findAppProcess(app, "Crash");
final String processName = app == null ? "system_server"
: (r == null ? "unknown" : r.processName);
handleApplicationCrashInner("crash", r, processName, crashInfo);
}
/* Native crash reporting uses this inner version because it needs to be somewhat
* decoupled from the AM-managed cleanup lifecycle
*/
void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
ApplicationErrorReport.CrashInfo crashInfo) {
EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
UserHandle.getUserId(Binder.getCallingUid()), processName,
r == null ? -1 : r.info.flags,
crashInfo.exceptionClassName,
crashInfo.exceptionMessage,
crashInfo.throwFileName,
crashInfo.throwLineNumber);
addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
crashApplication(r, crashInfo);
}
3.1 event log: AM_CRASH的輸出:
EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
UserHandle.getUserId(Binder.getCallingUid()), processName,
r == null ? -1 : r.info.flags,
crashInfo.exceptionClassName,
crashInfo.exceptionMessage,
crashInfo.throwFileName,
crashInfo.throwLineNumber);
am_crash: [5395,0,com.example.ritter.fcandanr,948485702,java.lang.NullPointerException,Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference,MainActivity.java,75]
am_crash: [
5395,
0,
com.example.ritter.fcandanr,
948485702,
java.lang.NullPointerException,
Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference,
MainActivity.java,
75]
4 addErrorToDropBox
呼叫dropbox服務儲存一些資訊到dropbox路徑
/**
* Write a description of an error (crash, WTF, ANR) to the drop box.
* @param eventType to include in the drop box tag ("crash", "wtf", etc.)
* @param process which caused the error, null means the system server
* @param activity which triggered the error, null if unknown
* @param parent activity related to the error, null if unknown
* @param subject line related to the error, null if absent
* @param report in long form describing the error, null if absent
* @param logFile to include in the report, null if none
* @param crashInfo giving an application stack trace, null if absent
*/
public void addErrorToDropBox(String eventType,
ProcessRecord process, String processName, ActivityRecord activity,
ActivityRecord parent, String subject,
final String report, final File logFile,
final ApplicationErrorReport.CrashInfo crashInfo) {
// NOTE -- this must never acquire the ActivityManagerService lock,
// otherwise the watchdog may be prevented from resetting the system.
final String dropboxTag = processClass(process) + "_" + eventType;
final DropBoxManager dbox = (DropBoxManager)
mContext.getSystemService(Context.DROPBOX_SERVICE);
// Exit early if the dropbox isn't configured to accept this report type.
if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
final StringBuilder sb = new StringBuilder(1024);
appendDropBoxProcessHeaders(process, processName, sb);
if (activity != null) {
sb.append("Activity: ").append(activity.shortComponentName).append("\n");
}
if (parent != null && parent.app != null && parent.app.pid != process.pid) {
sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
}
if (parent != null && parent != activity) {
sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
}
if (subject != null) {
sb.append("Subject: ").append(subject).append("\n");
}
sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
if (Debug.isDebuggerConnected()) {
sb.append("Debugger: Connected\n");
}
sb.append("\n");
// Do the rest in a worker thread to avoid blocking the caller on I/O
// (After this point, we shouldn't access AMS internal data structures.)
Thread worker = new Thread("Error dump: " + dropboxTag) {
@Override
public void run() {
if (report != null) {
sb.append(report);
}
if (logFile != null) {
try {
sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
"\n\n[[TRUNCATED]]"));
} catch (IOException e) {
Slog.e(TAG, "Error reading " + logFile, e);
}
}
if (crashInfo != null && crashInfo.stackTrace != null) {
sb.append(crashInfo.stackTrace);
}
String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
if (lines > 0) {
sb.append("\n");
// Merge several logcat streams, and take the last N lines
InputStreamReader input = null;
try {
java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
"-v", "time", "-b", "events", "-b", "system", "-b", "main",
"-b", "crash",
"-t", String.valueOf(lines)).redirectErrorStream(true).start();
try { logcat.getOutputStream().close(); } catch (IOException e) {}
try { logcat.getErrorStream().close(); } catch (IOException e) {}
input = new InputStreamReader(logcat.getInputStream());
int num;
char[] buf = new char[8192];
while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
} catch (IOException e) {
Slog.e(TAG, "Error running logcat", e);
} finally {
if (input != null) try { input.close(); } catch (IOException e) {}
}
}
dbox.addText(dropboxTag, sb.toString());
}
};
if (process == null) {
// If process is null, we are being called from some internal code
// and may be about to die -- run this synchronously.
worker.run();
} else {
worker.start();
}
}
4.1 dropbox中儲存什麼樣的檔名
當前的檔名是
dropbox中的檔名由dropboxTag決定:
dropboxTag = processClass(process):
private static String processClass(ProcessRecord process) {
if (process == null || process.pid == MY_PID) {
return "system_server";
} else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
return "system_app";
} else {
return "data_app";
}
}
4.2 dropbox中儲存的檔案內容是:
rocess: com.example.ritter.fcandanr
Flags: 0x38a8be46
Package: com.example.ritter.fcandanr v1 (1.0)
Build: Xiaomi/gemini/gemini:6.0.1/MXB48T/1.1.1:user/test-keys
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.view.View$DeclaredOnClickListener.onClick(View.java:4461)
at android.view.View.performClick(View.java:5207)
at android.view.View$PerformClick.run(View.java:21177)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5485)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4456)
... 9 more
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference
at com.example.ritter.fcandanr.MainActivity.onClickFC(MainActivity.java:75)
... 11 more
4.3 dropbox中也是可以儲存當前的logcat
但是受setting控制:
String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
5. 彈出的對話方塊crashApplication(r, crashInfo);
/**
* Bring up the "unexpected error" dialog box for a crashing app.
* Deal with edge cases (intercepts from instrumented applications,
* ActivityController, error intent receivers, that sort of thing).
* @param r the application crashing
* @param crashInfo describing the failure
*/
private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Message msg = Message.obtain();
msg.what = SHOW_ERROR_MSG;
HashMap data = new HashMap();
data.put("result", result);
data.put("app", r);
// MIUI ADD:
data.put("crash", crashInfo);
msg.obj = data;
mUiHandler.sendMessage(msg);
Binder.restoreCallingIdentity(origId);
}
6. system_server的異常也是按上面的流程處理的
system_server的異常也是會彈出介面?會導致framework 層重啟?