Refer:
Http://bigcat.easymorse.com /? P = 1152
Package Qianlong. qlmobile. ui; import Java. io. file; import Java. io. fileoutputstream; import Java. io. filenamefilter; import Java. io. printwriter; import Java. io. stringwriter; import Java. io. writer; import Java. lang. thread. uncaughtexceptionhandler; import Java. lang. reflect. field; import Java. util. arrays; import Java. util. properties; import Java. util. treeset; import android. content. context; import android. content. PM. Packageinfo; import android. content. PM. packagemanager; import android. content. PM. packagemanager. namenotfoundexception; import android. OS. build; import android. OS. logoff; import android. text. format. time; import android. util. log; import android. view. gravity; import android. widget. toast; public class crashhandler implements uncaughtexceptionhandler {/** debug log tag */public static final string tag = "Crash Handler ";/** whether to enable log output, enable it in debug state, and * disable it in release state to prompt program performance **/public static final Boolean DEBUG = false; /** default uncaughtexception class */private thread. uncaughtexceptionhandler mdefaulthandler;/** crashhandler instance */Private Static crashhandler instance;/** context object of the Program */private context mcontext; /** use properties to save device information and error stack information */private properties mdevicecrashinfo = new properties (); Private Static final string version_name = "versionname"; Private Static final string version_code = "versioncode"; Private Static final string stack_trace = "stack_trace "; /** error report file extension */Private Static final string crash_reporter_extension = ". cr ";/** ensure that there is only one crashhandler instance */private crashhandler () {}/ ** to obtain the crashhandler instance. Singleton mode */public static crashhandler getinstance () {If (instance = NULL) {Inst Ance = new crashhandler ();} return instance;}/*** initialize and register the context object. * obtain the default uncaughtexception processor of the system, * set the crashhandler as the default processor of the Program * @ Param CTX */Public void Init (context CTX) {mcontext = CTX; mdefaulthandler = thread. getdefaultuncaughtexceptionhandler (); thread. setdefaultuncaughtexceptionhandler (this);}/*** when uncaughtexception occurs, it will be transferred to this function for processing */@ override public void uncaughtexception (thread, Throwable ex) {If (! Handleexception (Ex) & mdefaulthandler! = NULL) {// if the user does not process the mdefaulthandler, the system's default exception processor is used to process the mdefaulthandler. uncaughtexception (thread, ex);} else {// sleep a moment later, end the program try {thread. sleep (5000);} catch (interruptedexception e) {log. E (TAG, "error:", e);} android. OS. process. killprocess (Android. OS. process. mypid (); system. exit (10) ;}/ *** custom error handling, collecting error information * Sending error reports and other operations are completed here. * developers can customize the exception handling logic as needed * @ Param ex * @ return true: If the exception information is processed, false */private is returned. Boolean handleexception (throwable ex) {If (EX = NULL) {log. W (TAG, "handleexception --- EX = NULL"); Return true;} final string MSG = ex. getlocalizedmessage (); If (MSG = NULL) {return false;} // use toast to display exception information new thread () {@ override public void run () {Looper. prepare (); Toast = toast. maketext (mcontext, "program error, about to exit: \ r \ n" + MSG, toast. length_long); toast. setgravity (gravity. center, 0, 0); toast. s How (); // msgprompt. showmsg (mcontext, "program error", MSG + "\ n point confirm to exit"); logoff. loop ();}}. start (); // collect device information collectcrashdeviceinfo (mcontext); // Save the error report file savecrashinfotofile (Ex); // send the Error Report to the server // sendcrashreportstoserver (mcontext ); return true;}/*** when the program starts, you can call this function to send a report not previously sent */Public void sendpreviusreportstoserver () {sendcrashreportstoserver (mcontext );} /*** send the Error Report to the server, including newly generated and not previously sent. * @ Param CTX * /Private void sendcrashreportstoserver (context CTX) {string [] crfiles = getcrashreportfiles (CTX); If (crfiles! = NULL & crfiles. length> 0) {treeset <string> sortedfiles = new treeset <string> (); sortedfiles. addall (arrays. aslist (crfiles); For (string filename: sortedfiles) {file Cr = new file (CTX. getfilesdir (), filename); postreport (CR); CR. delete (); // Delete the sent report} private void postreport (File file) {// todo send error report to server}/*** get error report file name * @ Param CTX * @ return */private string [] getcrashreportfiles (Co Ntext CTX) {file filesdir = CTX. getfilesdir (); filenamefilter filter = new filenamefilter () {public Boolean accept (File Dir, string name) {return name. endswith (crash_reporter_extension) ;}}; return filesdir. list (filter);}/*** Save the error message to the file * @ Param ex * @ return */private string savecrashinfotofile (throwable ex) {writer info = new stringwriter (); printwriter = new printwriter (Info ); Ex. printstacktrace (printwriter); throwable cause = ex. getcause (); While (cause! = NULL) {cause. printstacktrace (printwriter); cause = cause. getcause ();} string result = info. tostring (); printwriter. close (); mdevicecrashinfo. put ("exeption", Ex. getlocalizedmessage (); mdevicecrashinfo. put (stack_trace, result); try {// long timestamp = system. currenttimemillis (); time t = new time ("GMT + 8"); T. settonow (); // get the system time int date = T. year * 10000 + T. month * 100 + T. monthday; int time = T. Hour * 10000 + T. min ute * 100 + T. second; string filename = "crash-" + date + "-" + time + crash_reporter_extension; fileoutputstream trace = mcontext. openfileoutput (filename, context. mode_private); mdevicecrashinfo. store (trace, ""); trace. flush (); trace. close (); Return filename;} catch (exception e) {log. E (TAG, "an error occured while writing report file... ", e);} return NULL;}/*** collection program crash settings Backup information ** @ Param CTX */Public void collectcrashdeviceinfo (context CTX) {try {packagemanager PM = CTX. getpackagemanager (); packageinfo Pi = PM. getpackageinfo (CTX. getpackagename (), packagemanager. get_activities); If (Pi! = NULL) {mdevicecrashinfo. Put (version_name, Pi. versionname = NULL? "Not set": pi. versionname); mdevicecrashinfo. put (version_code, "" + pi. versioncode) ;}} catch (namenotfoundexception e) {log. E (TAG, "error while collect package Info", e);} // use reflection to collect device information. the build class contains various device information, such as the System Version Number and the device manufacturer. For more information, see Field [] fields = build. class. getdeclaredfields (); For (field: fields) {try {field. setaccessible (true); mdevicecrashinfo. put (field. getname (), "" + field. get (null); If (Debug) {log. D (TAG, field. getname () + ":" + field. get (null) ;}} catch (exception e) {log. E (TAG, "error while collect crash info", e );}}}}
Usage: // global data storage public class app extends application {private final static float heap_utilization = 0.75f; private final static int min_heap_size = 6*1024*1024; @ override public void oncreate () {super. oncreate (); // Exception Handling. comment out the two sentences when you do not need to handle them! Crashhandler = crashhandler. getinstance (); // register crashhandler. INIT (getapplicationcontext (); // optimize the memory. Optional values! Vmruntime. getruntime (). settargetheaputilization (heap_utilization); vmruntime. getruntime (). setminimumheapsize (min_heap_size); // changemetrics (this); // modify the screen density ......}}
When an exception occurs, write the file. The following is the file generated in data/data:
// Private Static final Boolean debugflag = false; // modify the screen densitypublic static void changemetrics (context) {displaymetrics curmetrics = context. getresources (). getdisplaymetrics (); If (! Debugflag) {If (curmetrics. densitydpi = displaymetrics. density_high) {displaymetrics metrics = new displaymetrics (); metrics. scaleddensity = 1.0f; metrics. density = 1.0f; metrics. densitydpi = displaymetrics. density_medium; metrics. xdpi = displaymetrics. density_medium; metrics. ydpi = displaymetrics. density_medium; metrics. heightpixels = curmetrics. heightpixels; metrics. widthpixels = curmetrics. widthpixels; context. getresources (). getdisplaymetrics (). setto (metrics) ;}} else {displaymetrics metrics = new displaymetrics (); metrics. scaleddensity = (float) (130/160. 0); metrics. density = (float) (130/160. 0); metrics. densitydpi = 130; metrics. xdpi = 130; metrics. ydpi = 130; metrics. heightpixels = curmetrics. heightpixels; metrics. widthpixels = curmetrics. widthpixels; context. getresources (). getdisplaymetrics (). setto (metrics );}}