Global processing of Android program errors

Source: Internet
Author: User
Tags http post
1. application crash report for Android

Turn: http://www.chengyunfeng.com/2010/07/application-crash-report-for-android

Will your android program crash! Does a user complain that the program crashes, but you cannot collect detailed information about the crash? Do you want to provide your users with a better user experience? Acra (Android program crash report) is a project that helps you collect information when your program crashes.

With acra, when your program crashes, you can send a crash report to Google doc, and then you can view the system information when the program crashes.

Project home: http://code.google.com/p/acra/

Document: http://code.google.com/p/acra/wiki/ACRAHowTo

 

Ii. Global processing of Android program errors

Turn: http://blog.csdn.net/liangguohuan/archive/2010/11/19/6022419.aspx

This article analyzes how to collect relevant error information when a program fails, and sends the error information to the server for developers to analyze and debug the program. The error message will be a powerful tool for debugging. With the error message, you can know the running status of the Program on various system versions and devices in a timely manner.
Error Handling
In general, errors in the ophone program will occur as shown in the following prompt dialog box:

 

Figure 1: ophone default error prompt

 

 

In this case, you only need to click "force close" to end the program. This article will show you how to disable this dialog box when a program error occurs.
With the increase of ophone devices and system versions, debugging programs on different devices and versions is becoming increasingly troublesome. Developers cannot purchase all devices to debug programs one by one. If the program runs normally on the simulator but an error occurs when it reaches the end user, in this case, if the program error stack information and specific device information can be collected, debugging programs can be of great help to developers.
To collect error information, we need to understand the use of two main APIs: Android. App. Application and Java. Lang. thread. uncaughtexceptionhandler. The following is a brief introduction to the two APIs.

Uncaughtexceptionhandler:The thread does not capture exceptions. The controller is used to handle exceptions that are not captured. If the program encounters an uncaptured exception, the forced close dialog box shown above is displayed by default. In this article, we will implement this interface and register it as the default program without capturing exception handling. In this way, when no exception is caught, you can perform some exception handling operations, such as collecting exception information and sending error reports.

Application:When developing an ophone application, it will deal with the activity, and the application will be used less. In ophone, an application is used to manage the global state of an application, such as loading a resource file. When the application starts, the application will first create and then start the corresponding activity or service according to the situation (intent. In this article, we will register an uncaptured exception processor in the application.

Uncaughtexceptionhandler interface implementation

First, create an ophone project (see other articles on ophonesdn for Project Creation). In this example, the project name is crashreporter and the package name is Org. goodev. and create a default activity named reportertest. Then create the crashhandler class to implement the uncaughtexceptionhandler interface and implement its function: Public void uncaughtexception (thread, throwable ex ). The crashhandler class implements the main processing logic of error reports. The code for this class is as follows (detailed comments will be provided in the Code to explain various processing situations ):

 

 

Package Org. goodev. CR; </P> <p> Import omitted ...; <br/>/** <br/> * uncaughtexception processing class. This class is available when the program encounters an uncaught exception <br/> * to take over the program, and records the error reports. <br/> */<br/> public class crashhandler implements uncaughtexceptionhandler {<br/>/** debug log tag */<br/> Public static final string tag = "crashhandler "; <br/>/** whether to enable log output and enable it in debug state, <br/> * close in release state to prompt program performance <br/> **/<br/> Public static final Boole An DEBUG = true; <br/>/** default uncaughtexception processing class */<br/> private thread. uncaughtexceptionhandler mdefaulthandler; <br/>/** crashhandler instance */<br/> Private Static crashhandler instance; <br/>/** context object of the Program */<br/> private context mcontext; </P> <p>/** use properties to save device information and error stack information */<br/> private properties mdevicecrashinfo = new properties (); <br/> Private Static final string version_name = "Versionname"; <br/> Private Static final string version_code = "versioncode"; <br/> Private Static final string stack_trace = "stack_trace "; <br/>/** error report file extension */<br/> Private Static final string crash_reporter_extension = ". cr "; </P> <p>/** ensure that there is only one crashhandler instance */<br/> private crashhandler () {}< br/>/** obtain the crashhandler instance, Singleton mode */<br/> Public static crashhandler getinstance () {<br/> If (in Stance = NULL) {<br/> instance = new crashhandler (); <br/>}< br/> return instance; <br/>}</P> <p>/** <br/> * initialize and register the context object. <br/> * obtain the default uncaughtexception processor, <br/> * set the crashhandler as the default processor of the Program <br/> * @ Param CTX <br/> */<br/> Public void Init (context CTX) {<br/> mcontext = CTX; <br/> mdefaulthandler = thread. getdefaultuncaughtexceptionhandler (); <br/> thread. setdefaultuncaughtexc Eptionhandler (this ); <br/>}</P> <p>/** <br/> * this function is transferred when uncaughtexception occurs. <br/> */<br/> @ override <br/> Public void uncaughtexception (thread, throwable ex) {<br/> If (! Handleexception (Ex) & mdefaulthandler! = NULL) {<br/> // if the user does not handle the error, the system uses the default exception processor to handle the error. <br/> mdefaulthandler. uncaughtexception (thread, ex); <br/>}else {<br/> // end the program after a short sleep <br/> try {<br/> thread. sleep (3000); <br/>} catch (interruptedexception e) {<br/> log. E (TAG, "error:", e); <br/>}< br/> android. OS. process. killprocess (Android. OS. process. mypid (); <br/> system. exit (10); <br/>}</P> <p>/** <br/> * handle custom errors, collect error messages <br/> * Send The error reports and other operations are completed here. <br/> * developers can customize the exception handling logic based on their own situations <br/> * @ Param ex <br/> * @ return true: If the exception information is processed; otherwise, false is returned. <br/> */<br/> private Boolean handleexception (throwable ex) {<br/> If (EX = NULL) {<br/> return true; <br/>}< br/> final string MSG = ex. getlocalizedmessage (); <br/> // use toast to display exception information <br/> New thread () {<br/> @ override <br/> Public void run () {<br/> logoff. prepare (); <br/> toast. maketext (Mcontext, "program error:" + MSG, toast. length_long) <br/>. show (); <br/> logoff. loop (); <br/>}</P> <p> }. start (); <br/> // collect device information <br/> collectcrashdeviceinfo (mcontext ); <br/> // Save the error report file <br/> string crashfilename = savecrashinfotofile (Ex ); <br/> // send the Error Report to the server <br/> sendcrashreportstoserver (mcontext); <br/> return true; <br/>}</P> <p>/** <br/> * When the program is started, you can call this function to send reports that were not previously sent <br/> */<br/> Public void s Endpreviusreportstoserver () {<br/> sendcrashreportstoserver (mcontext); <br/>}</P> <p>/** <br/> * sends the Error Report to the server, contains newly generated and not previously sent. <br/> * @ Param CTX <br/> */<br/> private void sendcrashreportstoserver (context CTX) {<br/> string [] crfiles = getcrashreportfiles (CTX); <br/> If (crfiles! = NULL & crfiles. length> 0) {<br/> treeset <string> sortedfiles = new treeset <string> (); <br/> sortedfiles. addall (arrays. aslist (crfiles); </P> <p> for (string filename: sortedfiles) {<br/> file Cr = new file (CTX. getfilesdir (), filename); <br/> postreport (CR); <br/> Cr. delete (); // delete a report that has been sent <br/>}</P> <p> private void postreport (File file) {<br/> // todo sends an error report to the server using http post <B R/> // I will not detail it here, developers can submit error reports based on other network operations on ophonesdn <br/> // tutorial <br/>}</P> <p>/** <br/> * get error report file name <br/> * @ Param CTX <br/> * @ return <br/> */<br/> private string [] getcrashreportfiles (context CTX) {<br/> file filesdir = CTX. getfilesdir (); <br/> filenamefilter filter = new filenamefilter () {<br/> Public Boolean accept (File Dir, string name) {<br/> return name. endswith (crash_reporter_extension); <BR/>}< br/>}; <br/> return filesdir. list (filter ); <br/>}< br/>/** <br/> * Save the error message to the file <br/> * @ Param ex <br/> * @ return <br /> */<br/> private string savecrashinfotofile (throwable ex) {<br/> writer info = new stringwriter (); <br/> printwriter = new printwriter (Info); <br/> ex. printstacktrace (printwriter); </P> <p> throwable cause = ex. getcause (); <br/> while (cause! = NULL) {<br/> cause. printstacktrace (printwriter); <br/> cause = cause. getcause (); <br/>}</P> <p> string result = info. tostring (); <br/> printwriter. close (); <br/> mdevicecrashinfo. put (stack_trace, result); </P> <p> try {<br/> long timestamp = system. currenttimemillis (); <br/> string filename = "crash-" + timestamp + crash_reporter_extension; <br/> fileoutputstream trace = mcontext. openfileoutput (Filename, <br/> context. mode_private); <br/> mdevicecrashinfo. store (trace, ""); <br/> trace. flush (); <br/> trace. close (); <br/> return filename; <br/>} catch (exception e) {<br/> log. E (TAG, "an error occured while writing report file... ", e); <br/>}< br/> return NULL; <br/>}</P> <p>/** <br/> * collect device information for program crash <br/> * @ Param CTX <br/> */<br/> Public void collectcrashdeviceinfo (context CT X) {<br/> try {<br/> packagemanager PM = CTX. getpackagemanager (); <br/> packageinfo Pi = PM. getpackageinfo (CTX. getpackagename (), <br/> packagemanager. get_activities); <br/> If (Pi! = NULL) {<br/> mdevicecrashinfo. Put (version_name, <br/> pi. versionname = NULL? "Not set": pi. versionname); <br/> mdevicecrashinfo. put (version_code, Pi. versioncode); <br/>}< br/>} catch (namenotfoundexception e) {<br/> log. E (TAG, "error while collect package Info", e); <br/>}< br/> // use reflection to collect device information. the build class contains various device information. <br/> // For example, the system version number, device manufacturer and other useful information for debugging programs <br/> // For more information, see <br/> Field [] fields = build. class. getdeclaredfields (); <br/> for (field: fields) {<br/> try {<br/> field. setaccessible (true); <br/> mdevicecrashinfo. put (field. getname (), field. get (null); <br/> If (Debug) {<br/> log. D (TAG, field. getname () + ":" + field. get (null); <br/>}< br/>}catch (exception e) {<br/> log. E (TAG, "error while collect crash info", e ); <br/>}</P> <p>} 

 

In the preceding crashhandler implementation, when an error occurs, use toast to display the error information, collect the error report, and save it in the file. Please implement the Error Report code by yourself. In the uncaughtexception function, thread. Sleep (3000) is called to stop the thread for a while to display the toast information to the user and kill the program. This code can be removed if you do not need toast to display information. In addition to toast, developers can also use notification to Display Error content and allow users to choose whether to submit error reports rather than automatically submit reports. For more information about notification implementation, see notificationmanager. When sending an error report, you can first check whether the Network is available. If it is unavailable, it can be sent in the future when the Network is available. The Network Monitoring code is as follows:

 

/** <Br/> * check whether the network connection is available <br/> * @ Param CTX <br/> * @ return true is available; false unavailable <br/> */<br/> private Boolean isnetworkavailable (context CTX) {<br/> connectivitymanager CM = <br/> (connectivitymanager) CTX. getsystemservice (context. connectivity_service); <br/> If (Cm = NULL) {<br/> return false; <br/>}< br/> networkinfo [] netinfo = cm. getallnetworkinfo (); <br/> If (netinfo = NULL) {<br/> return false; <br/>}< br/> for (INT I = 0; I <netinfo. length; I ++) {<br/> If (netinfo [I]. isconnected () {<br/> return true; <br/>}< br/> return false; <br/>} 

 

The following information is collected on the simulator and the author's mobile phone (Dell mini3i ophone1.5 system:

 

 

Figure 2: simulator Information

Figure 3: Dell mini3i device information

 

 

 

Application Implementation

Implement a custom application to register crashhandler. The Code is as follows:

 

 

Public class crashapplication extends application {</P> <p> @ override <br/> Public void oncreate () {<br/> super. oncreate (); <br/> crashhandler = crashhandler. getinstance (); <br/> // register crashhandler <br/> crashhandler. init (getapplicationcontext (); <br/> // sends a report not previously sent (optional) <br/> crashhandler. sendpreviusreportstoserver (); <br/>}</P> <p>} 

 

 

Register in androidmanifest. xml

Finally, you only need to register the crashapplication in androidmanifest. xml. The Code is as follows:

 

<? XML version = "1.0" encoding = "UTF-8"?> <Br/> <manifest xmlns: Android = "http://schemas.android.com/apk/res/android" <br/> package = "org. goodev. cr "<br/> Android: versioncode =" 1 "<br/> Android: versionname =" 1.0 "> <br/> <application Android: icon = "@ drawable/icon" Android: Label = "@ string/app_name" <br/> Android: Name = ". crashapplication "> <br/> <activity Android: Name = ". reportertest "<br/> Android: Label =" @ string/app_name "> <br/> <intent-filter> <br/> <action Android: Name =" android. intent. action. main "/> <br/> <category Android: Name =" android. intent. category. launcher "/> <br/> </intent-filter> <br/> </activity> <br/> </Application> <br/> </manifest> 

 

 

Summary:Through the example in this article, developers can collect detailed crash information in the program to facilitate program debugging. If your program does not have this function, please join. Crashreporter.zip contains the project files and resources used in this document.

Author profile:Cheng Yunfeng, named icess, is currently working at Hang Seng electronics R & D center in Hangzhou. He prefers Java open source technology.
Personal Website: http://www.chengyunfeng.com/

(Statement: The copyright of news and articles on this website belongs to the ophone SDN website. If you need to repost it, please contact our editing team. No media, website, or individual may repost in any form without the authorization of the written agreement on this website. For media and websites that have obtained the authorization of this Agreement, please indicate the source of the manuscript when reprinting and using it .)


 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.