How Android captures crash information for apps

Source: Internet
Author: User

Reprint Please specify source: http://blog.csdn.net/fishle123/article/details/50823358

Our application will inevitably occur crash, assuming that we can use Logcat to view exception information during the debugging phase. But what if after the application is published? Assuming that we are crash on the user's side, assuming we can capture these crash information, it is very helpful to locate the crash cause and fix the problem.

The application of crash can be a Java layer of the exception caused by the native layer may be caused, the following separate to see how to deal with.

1 uncaught exception handling for Java layers

Let's take a look at the Java layer's crash information collection. Capturing the Java layer's crash information is not difficult. Android has provided an interface to help us monitor the system's uncaught anomalies: Using Thread.setdefaultuncaughtexceptionhandler allows us to easily monitor the application regardless of any accidental crash.

First look at the Thread.setdefaultuncaughtexceptionhandler method:

/** * Sets the default uncaught exception handler. This handler was invoked in * case any Thread dies due to an unhandled exception. * * @param handler * The            handler to set or null. */public static void Setdefaultuncaughtexceptionhandler (UNCAUGHTEXCEP Tionhandler handler) {    Thread.defaultuncaughthandler = handler;}

From the gaze of thread.setdefaultuncaughtexceptionhandler this method can be seen: when in process (since Thread.defaultuncaughthandler is a static variable, This is therefore valid for all threads throughout the process) regardless of the thread in which an uncaught exception occurs. Will call the handler set here. Let's take a look at the Uncaughtexceptionhandler class:

/** * Implemented by objects, want to handle cases where a thread was being * terminated by an uncaught exception. Upon such termination, the handler * is notified of the terminating thread and causal exception. If there is * No explicit handler set then the thread ' s group is the default handler. */public static interface Uncaughtexceptionhandler {    /** * The thread is being terminated by an     uncaught exception . Further     * Exceptions thrown in this method     is prevent the remainder of the * method from executing, but is other Wise ignored.     *     * @param thread the thread that has a uncaught exception     * @param ex The exception that is thrown     */    V OID uncaughtexception (thread thread, Throwable ex);}

From the source code can be seen. Uncaughtexceptionhandler is actually an interface, it simply defines a method uncaughtexception (thread thread, Throwable ex), This method is called when the thread terminates because it encounters an uncaught exception.

Suppose we want to capture the crash information of an application, then define a uncaughtexceptionhandler of our own, and of course we need to save the crash information in our own uncaughtexceptionhandler. When necessary, it can be uploaded to our server, so it is very convenient to collect the user's crash information.

2 exception handling of native layer

Assuming that our application is used in C + +, you also need to collect native layer exception handling.

We all know that. The bottom of Android is Linux-based, so an uncaught exception to the native layer can be handled by capturing the signal. The native layer assumes that an abnormal termination will emit a sigkill signal. We can use the sigaaction to register a signal processing function to process the sigkill signal, so that we can collect the uncaught anomaly of the native layer.

Here is an approximate code framework:

void Sigkill_handler (int signo) {   ///print stack, and write to file}void install () {    struct sigaction Act, oldact;    Act.sa_handler = Sigkill_handler;    Sigaddset (&act.sa_mask, SIGKILL);    Sigaction (SIGKILL, &act, &oldact);//Register signal processing function ...    }

3 implementation

Combined with the above introduction. Here's a uncaughtexceptionhandler to define your own. This example only handles the crash collection of the Java layer and saves the collected crash information to the SD card. Here is a name for our own defined Crash processor named APPCR (Application Crash Response).

First define the Errorreporter, which implements the Uncaughtexceptionhandler:

public class Errorreporter implements Uncaughtexceptionhandler {private final application mcontext;    Private final Reporterexecutor Mreporterexecutor;        Errorreporter (Application Context, Boolean enabled) {Mcontext = context; Final Thread.uncaughtexceptionhandler Defaultexceptionhandler = Thread. Getdefaultuncaughtexceptionhandler (        );        Mreporterexecutor = new Reporterexecutor (context, Defaultexceptionhandler);        mreporterexecutor.setenabled (enabled);    Thread.setdefaultuncaughtexceptionhandler (this); } @Override public void Uncaughtexception (final Thread thread,final Throwable ex) {//TODO auto-generated Me        Thod stub logutil.i (Appcr.log_tag, "catch uncaughtexception");    Mreporterexecutor.execute (thread, ex); } public void SetEnabled (Boolean enabled) {logutil.i (Appcr.log_tag, "APPCR is" + (enabled)

"Enabled": "Disabled") + "for" + Mcontext.getpackagename ()); }}

Reporterexecutor will call Thread.setdefaultuncaughtexceptionhandler (this) to change the default Uncaughtexceptionhandler. When an uncaught exception occurs. Call Mreporterexecutor.execute (thread, ex) to handle the exception.

In Reporterexecutor, the exception information and the operating system information are saved to the file.

public class Reporterexecutor {public static final String TAG = ReporterExecutor.class.getSimpleName ();    Private Context Mcontext;    Private Boolean menabled = false;    Private final Thread.uncaughtexceptionhandler Mdefaultexceptionhandler;    Private File Mcrashinfofile; Public Reporterexecutor (context context, Thread.uncaughtexceptionhandler Defaultedexceptionhand        LER) {Mcontext = context;        Mdefaultexceptionhandler = Defaultedexceptionhandler; if (Environment.MEDIA_MOUNTED.equals (Environment.getexternalstoragestate ())) {File Path = Environment.getexter            Nalstoragedirectory ();            File dir = new file (path, "Blefairy");            if (!dir.exists ()) {dir.mkdirs ();            } mcrashinfofile = new File (dir, Getcrashfilename ());                if (!mcrashinfofile.exists ()) {try {mcrashinfofile.createnewfile ();     } catch (IOException e) {               TODO auto-generated Catch block E.printstacktrace ();    }}}} public boolean isenabled () {return menabled;    The public void SetEnabled (Boolean enabled) {menabled = enabled;            } public void execute (thread thread, Throwable ex) {if (!menabled) {endapplication (thread, ex);        Return        }//Log crash info to file LOG.W (Appcr.log_tag, "getsysinfo.");        Crashreportdata data = crashreportdata.produce (thread, ex, mcontext);        Data.writetofile (Mcrashinfofile);           Endapplication (thread, ex);            } private void Endapplication (thread thread, Throwable ex) {if (Mdefaultexceptionhandler! = null) {            LOG.W (Appcr.log_tag, "execute default uncaughtexception handler.");        Mdefaultexceptionhandler.uncaughtexception (thread, ex);            } else {LOG.W (Appcr.log_tag, "kill process and exit.");Android.os.Process.killProcess (Android.os.Process.myPid ());        System.exit (10);        }} private String Getcrashfilename () {StringBuilder ret = new StringBuilder ();        Calendar calendar = Calendar.getinstance ();        Ret.append ("Crash_");        Ret.append (Calendar.get (calendar.year));        int month = Calendar.get (calendar.month) +1;        int date = Calendar.get (calendar.date);        if (Month <) {Ret.append ("0");        } ret.append (month);        if (date<10) {ret.append ("0");        } ret.append (date);        Ret.append (". txt");    return ret.tostring (); }}

The Crashreportdata class is used to hold exception information:

public class Crashreportdata {private final String info;    Private Crashreportdata (String crashInfo) {this.info = CrashInfo; } public static crashreportdata produce (thread thread, throwable Ex, Context context) {Bytearrayoutputstream OU        t = new Bytearrayoutputstream ();        PrintStream print = new PrintStream (out);        Out.tostring ();        Print.append ("Crahtime:" + timeutil.getcurtimestring ()). Append ("\ n");        Print.append (Sysinfo.getsysinfo (context)). Append ("\ n");        Print.append (Thread.getname ()). Append ("(threadid=" + thread.getid () + ")"). Append ("\ n");        Print.append (Ex.getmessage ()). Append ("\ n");        Ex.printstacktrace (print);    return new Crashreportdata (out.tostring ());        The public void WriteToFile (file file) {PrintWriter printer = null; try {//Append to the end of crash file Bufferedoutputstream out = new Bufferedoutputstream (New Fil            Eoutputstream (file, true)); Printer = NEW PrintWriter (out);            PRINTER.PRINTLN (info);        Printer.flush ();        } catch (IOException e) {//TODO auto-generated catch block E.printstacktrace ();            } finally {if (printer! = null) {printer.close ();        } LOGUTIL.W (Appcr.log_tag, "write exception info to file over.");        }} @Override public String toString () {//TODO auto-generated method stub return info;    return super.tostring (); }}

Sysino class:

public class SysInfo {public    static String Getsysinfo (context context) {        StringBuilder info = new StringBuilder () ;        Info.append ("Osversion=android"). Append (Build.VERSION.RELEASE). Append ("\ n");        Info.append ("model="). Append (Build.model). Append ("\ n");        Info.append ("brand="). Append (Build.brand). Append ("\ n");        Logutil.i (Appcr.log_tag, "sys info collect over.");        return info.tostring ();    }}

Use APPCR to install our crash Processor:

public class APPCR {public    static final String log_tag=appcr.class.getsimplename ();    private static Errorreporter Merrorreporter;    public static void Init (Application application) {        init (application,true);    }    public static void Init (application Application,boolean enabled) {        merrorreporter = new Errorreporter (Application, enabled);}    }

Installing the above-defined APPCR in the application is possible:

public class Beaconapplication extends application {    private final String TAG = "Beaconfairy.beaconapplication";        @Override public    void OnCreate () {        super.oncreate ();        Appcr.init (this,true);    }}

It is important to note that we need to define our own application, then change manifest to be able to, and remember to add the rights to write the SD card:

<application        android:name= ". Beaconapplication "        android:allowbackup=" true "        android:allowtaskreparenting=" true "        android:icon=" @ Drawable/ic_launcher "        android:label=" @string/app_name "        android:theme=" @style/apptheme ">         ........</application>
To request permission to write an SD card:

<uses-permission android:name= "Android.permission.WRITE_EXTERNAL_STORAGE"/>

So far, our own definition of the crash information collection program APPCR is complete.

How Android captures crash information for apps

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.