Global exceptions and errors of Android Processors

Source: Internet
Author: User
Tags http post

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, a prompt dialog box appears when an error occurs in the ophone program.
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 exception controller not captured by the thread is used to handle exceptions 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 is rarely used. 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;

Import omitted ...;
/**
* Uncaughtexception processing class. This class is available when the program encounters an uncaught exception.
* Takes over the program and records the error reports sent.
*
*/
Public class crashhandler implements uncaughtexceptionhandler {
/** Debug log tag */
Public static final string tag = "crashhandler ";
/** Whether to enable log output and enable it in debug status,
* Shut down in the release status to prompt Program Performance
**/
Public static final Boolean DEBUG = true;
/** Default uncaughtexception processing 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 (){}
/** Obtain the crashhandler instance. Singleton mode */
Public static crashhandler getinstance (){
If (instance = NULL ){
Instance = new crashhandler ();
}
Return instance;
}

/**
* Initialize and register the context object,
* Obtain the default uncaughtexception processor,
* 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 is transferred to this function for processing.
*/
@ Override
Public void uncaughtexception (thread, throwable ex ){
If (! Handleexception (Ex) & mdefaulthandler! = NULL ){
// If the user does not handle the exception, the system's default exception processor will handle the exception.
Mdefaulthandler. uncaughtexception (thread, ex );
} Else {
// End the program after sleep.
Try {
Thread. Sleep (3000 );
} 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 based on their own situations.
* @ Param ex
* @ Return true: If the exception information is processed, false is returned.
*/
Private Boolean handleexception (throwable ex ){
If (EX = NULL ){
Return true;
}
Final string MSG = ex. getlocalizedmessage ();
// Use toast to display exception information
New thread (){
@ Override
Public void run (){
Logoff. Prepare ();
Toast. maketext (mcontext, "program error:" + MSG, Toast. length_long)
. Show ();
Logoff. Loop ();
}

}. Start ();
// Collect device information
Collectcrashdeviceinfo (mcontext );
// Save the error report file
String crashfilename = savecrashinfotofile (Ex );
// Send an error report to the server
Sendcrashreportstoserver (mcontext );
Return true;
}

/**
* When the program starts, you can call this function to send reports that have not been sent before.
*/
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 a report that has been sent
}
}
}

Private void postreport (File file ){
// Todo sends an error report to the server using HTTP POST
// I will not detail it here. developers can perform other network operations based on ophonesdn.
// Submit the Error Report in the tutorial
}

/**
* Get the error report file name
* @ Param CTX
* @ Return
*/
Private string [] getcrashreportfiles (context 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 (stack_trace, result );

Try {
Long timestamp = system. currenttimemillis ();
String filename = "crash-" + timestamp + 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;
}

/**
* Collect device information for program crash
*
* @ 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,
// For example, the system version number, device manufacturer, and other useful information for debugging programs
// 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 );
}

}

}

}

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:
/**
* Check whether the network connection is available
* @ Param CTX
* @ Return true available; false unavailable
*/
Private Boolean isnetworkavailable (context CTX ){
Connectivitymanager CM =
(Connectivitymanager) CTX. getsystemservice (context. connectivity_service );
If (Cm = NULL ){
Return false;
}
Networkinfo [] netinfo = cm. getallnetworkinfo ();
If (netinfo = NULL ){
Return false;
}
For (INT I = 0; I <netinfo. length; I ++ ){
If (netinfo [I]. isconnected ()){
Return true;
}
}
Return false;
}

 

Application Implementation

Implement a custom application to register crashhandler. The Code is as follows:
Public class crashapplication extends application {

@ Override
Public void oncreate (){
Super. oncreate ();
Crashhandler = crashhandler. getinstance ();
// Register crashhandler
Crashhandler. INIT (getapplicationcontext ());
// Send a report that has not been sent before (optional)
Crashhandler. sendpreviusreportstoserver ();
}

}

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"?>
<Manifest xmlns: Android = "http://schemas.android.com/apk/res/android"
Package = "org. goodev. cr"
Android: versioncode = "1"
Android: versionname = "1.0" type = "codeph" text = "/codeph">
<Application Android: icon = "@ drawable/icon" Android: Label = "@ string/app_name"
Android: Name = ". crashapplication">
<Activity Android: Name = ". reportertest"
Android: Label = "@ string/app_name">
<Intent-filter>
<Action Android: Name = "android. Intent. Action. Main"/>
<Category Android: Name = "android. Intent. Category. launcher"/>
</Intent-filter>
</Activity>
</Application>
</Manifest>

 

Address: http://blog.csdn.net/zhong_ch/archive/2011/04/27/6366023.aspx

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.