Android Exception Capture

Source: Internet
Author: User

When users use the app, if the app suddenly quits without warning, there's no message. I think it's the worst kind of user experience, and if it's my guess, just uninstall the app. Therefore, as an Android developer, there must be a process for this to happen. Otherwise, you can't forgive yourself for most of the most perfect programmers. In fact, catch the global exception, you can also do a logout processing, such as the user in the app, the server will be seesion to determine whether the user online, if the app does not log off the server after the exception of the online record, it will cause the user is actually offline and on the service side of the record as online error. Users may not be able to log in if they log in again.

Now that the capture of global exceptions is so important, how do we implement such an important function?

The most important thing is to inherit the Uncaughtexceptionhandler interface. Uncaught exception handling is first controlled by the thread, then controlled by the thread's Threadgroup object, and finally by the uncaught default exception handler. If the thread does not set an explicit uncaught exception handler, and the thread Group of the thread (including the parent thread group) does not specifically specify its Uncaughtexception method, the default handler's Uncaughtexception method is called. By setting the default exception handlers that are not caught, the application can change the uncaught exception handling (such as logging to a specific device or file) for threads that have accepted any "default" behavior provided by the system.

The implementation of the Capture tool class is as follows:

 PackageCom.example.crash;ImportJava.lang.Thread.UncaughtExceptionHandler;ImportAndroid.content.Context;ImportAndroid.os.Looper;ImportAndroid.util.Log;ImportAndroid.widget.Toast; Public classCrashhandlerImplementsUncaughtexceptionhandler { Public Static FinalString TAG = "Crashhandler"; //system default Uncaughtexception processing class    PrivateThread.uncaughtexceptionhandler Mdefaulthandler; //Crashhandler Instances    Private StaticCrashhandler INSTANCE =NewCrashhandler (); //context object for the program    PrivateContext Mcontext; /**guaranteed only one Crashhandler instance*/      PrivateCrashhandler () {}/**get Crashhandler instances, Singleton mode*/       Public StaticCrashhandler getinstance () {returnINSTANCE; }        /*** Initialize * *@paramContext*/       Public voidinit (Context context) {Mcontext=context; //get the system default Uncaughtexception processorMdefaulthandler =Thread.getdefaultuncaughtexceptionhandler (); //set the Crashhandler as the default processor for the programThread.setdefaultuncaughtexceptionhandler ( This); } @Override Public voiduncaughtexception (thread thread, Throwable ex) {if(!handleexception (ex) && Mdefaulthandler! =NULL) {             //let the system default exception handler handle if the user does not handlemdefaulthandler.uncaughtexception (thread, ex); } Else {              Try{Thread.Sleep (3000); } Catch(interruptedexception e) {log.e (TAG,"Error:", E); }              //Exit Programandroid.os.Process.killProcess (Android.os.Process.myPid ()); System.exit (1); }            }    Private BooleanHandleException (Throwable ex) {if(ex = =NULL) {              return false; }          //use Toast to display exception information        NewThread () {@Override Public voidrun () {looper.prepare (); Toast.maketext (Mcontext,"Sorry, the program is out of the ordinary and is about to exit.", Toast.length_long). Show ();              Looper.loop ();                  }}.start (); //Other operations can be performed here, such as obtaining device information, performing an exception logout request, saving the error log locally or sending it to the server                return true; }}

In addition, because we need to catch global exceptions, we need to start in application, so we also need to implement application.

The specific implementation is as follows:

 package   Com.example.crash;  import   android.app.Application;  public  class     MyApplication extends   application{@Override  public  void   OnCreate () { //  TODO Auto-generated met        Hod stub  super  .oncreate ();          Crashhandler crashhandler  = Crashhandler.getinstance ();    Crashhandler.init (Getapplicationcontext ()); }}

As you can see from the code, when we start application, we get the Crashhandler instance and initialize it.

If you want to use this myapplication also must be set in the configuration file, otherwise it will start the Android default application, set the following:

< Application         Android:allowbackup = "true"         android:name= "Com.example.crash.MyApplication"        android:icon= "@ Drawable/ic_launcher "        android:label=" @string/app_name "        android: Theme= "@style/apptheme">
..................................

The most important is the Android:name= "Com.example.crash.MyApplication" code, which represents the use of our own application.

OK, the preparation is done, and the next step is to simulate an anomaly. We simulate an uncaught null pointer exception.

The scenario is that the second activity has an exception when the first activity jumps to the second activity.

Because the layout is simple, no code is posted.

First activity:

 Public classMainactivityextendsActivity {@Overrideprotected voidonCreate (Bundle savedinstancestate) {Super. OnCreate (savedinstancestate);        Setcontentview (R.layout.activity_main); Button btn=(Button) Findviewbyid (R.ID.BTN); Btn.setonclicklistener (NewOnclicklistener () {@Override Public voidOnClick (View v) {Intent inent=NewIntent (mainactivity. This, Toactivity.class);                            StartActivity (inent);    }        }); }}

A second activity:

 Public class extends Activity {        private  Button btn2;    @Override    protectedvoid  onCreate (Bundle savedinstancestate) {        / /  TODO auto-generated method stub        Super. OnCreate (savedinstancestate);        Setcontentview (R.layout.toactivity_main);         // btn2 = (Button) Findviewbyid (R.ID.BTN2);        Btn2.settext ("Save");}    }

The specific operating results are as follows:

It is important to note that if the toast information does not pop up when the exception is caught, it may be caused by a null context.

If you have an exception in use, you can save the exception as text locally, because we have caught a global exception so there is very little exception information in the log, so keeping the exception as text locally is also convenient for developers to view.

When a global exception is caught, other actions can be taken, such as obtaining device information, executing an exception logout request, saving the error log locally or sending it to the server.

Such as:

/*** Collect device parameter information *@paramCTX*/       Public voidCollectdeviceinfo (Context ctx) {Try{packagemanager pm=Ctx.getpackagemanager (); PackageInfo Pi=Pm.getpackageinfo (Ctx.getpackagename (), packagemanager.get_activities); if(Pi! =NULL) {String versionname= Pi.versionname = =NULL? "NULL": Pi.versionname; String Versioncode= Pi.versioncode + ""; Infos.put ("Versionname", Versionname); Infos.put ("Versioncode", Versioncode); }          } Catch(namenotfoundexception e) {log.e (TAG,"An error occured when collect package info", E); } field[] fields= Build.class. Getdeclaredfields ();  for(Field field:fields) {Try{field.setaccessible (true); Infos.put (Field.getname (), Field.get (NULL). toString ()); LOG.D (TAG, Field.getname ()+ ":" + field.get (NULL)); } Catch(Exception e) {log.e (TAG,"An error occured when collect crash info", E); }          }      }

/*** Save the error message to the file * *@paramex *@returnreturns the file name for easy transfer of files to the server*/      PrivateString Savecrashinfo2file (Throwable ex) {StringBuffer SB=NewStringBuffer ();  for(Map.entry<string, string>Entry:infos.entrySet ()) {String key=Entry.getkey (); String value=Entry.getvalue (); Sb.append (Key+ "=" + value + "\ n"); } writer writer=NewStringWriter (); PrintWriter PrintWriter=NewPrintWriter (writer);          Ex.printstacktrace (PrintWriter); Throwable cause=Ex.getcause ();  while(Cause! =NULL) {cause.printstacktrace (printwriter); Cause=Cause.getcause ();          } printwriter.close (); String result=writer.tostring ();          Sb.append (result); Try {              Longtimestamp =System.currenttimemillis (); String Time= Formatter.format (NewDate ()); String FileName= "crash-" + Time + "-" + timestamp + ". Log"; if(Environment.getexternalstoragestate (). Equals (environment.media_mounted)) {String path= "/sdcard/crash/"; File dir=NewFile (path); if(!dir.exists ())                  {Dir.mkdirs (); } FileOutputStream Fos=NewFileOutputStream (path +fileName);                  Fos.write (Sb.tostring (). GetBytes ());              Fos.close (); }              returnFileName; } Catch(Exception e) {log.e (TAG,"An error occured while writing file ...", E); }          return NULL; }

Thanks for the blog: http://blog.csdn.net/liuhe688/article/details/6584143 provides help.

This example is done based on an instance of http://blog.csdn.net/liuhe688/article/details/6584143.

Attached demo:http://download.csdn.net/detail/af74776/8381245

Android Exception Capture

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.