Self-defining uncaught exception handling for application

Source: Internet
Author: User
Tags throwable

Recently due to work reasons. When developing an Android app, it was found that the app throws an uncaught exception when an exception such as a null pointer appears. The Android system has a default uncaught exception handler, and the default behavior is to end the corresponding thread, but it does not exit the program directly, and when the app has a background service. Services are also always executing, assuming that the service will throw some exception information when requesting the network, and that using it again in an application that does not completely exit will further cause an exception, which is not good for the user experience.

Therefore, you should exit the app immediately after an exception occurs, and then restart the app. A lot of information was searched on the internet. Very many are not very good to solve the problem, because Android may start very much activity, and before the end of the application process should finish the activity in all tasks, otherwise there will be some unwanted results, of course, the end of the service.

There is an Thread.uncaughtexceptionhandler interface in Android that requires this interface to be implemented. and implement the Uncaughtexception function. The following is directly affixed to the relevant code:

public class Mycrashhandler implements Thread.uncaughtexceptionhandler {
private static final String TAG = "Mycaughtexception";
Application
Private MyApplication mapplication;
System default non-catching exception handler
Private Thread.uncaughtexceptionhandler Mdefaulthandler;
Self-defined non-catching exception handler
private static Mycrashhandler gcaughtexception;

/**
* Protection of single case mode
*/
Private Cepm360crashhandler () {

}

/**
* Single case mode
* @param application
* @return
*/
public static synchronized Mycrashhandler getinstance (application application) {
if (gcaughtexception = = null) {
Gcaughtexception = new Mycrashhandler (application);
}
return gcaughtexception;
}

/**
* Constructor function
* @param application
*/
Private Mycrashhandler (Application application) {
Mapplication = (myapplication) application;
Get the system default Uncaughtexceptionhandler
Mdefaulthandler = Thread.getdefaultuncaughtexceptionhandler ();
Setting the exception handler
Thread.setdefaultuncaughtexceptionhandler (this);
}


/**
* No exception handling function is caught
*/
@Override
public void uncaughtexception (thread thread, Throwable ex) {
LOG.E (TAG, "Ocurrs uncaughtexception!");
Print Stack
Ex.printstacktrace ();

Intent Intent = new Intent (mapplication, Myservice.class);
if (!handleexception (ex) && Mdefaulthandler! = null) {
Mdefaulthandler.uncaughtexception (thread, ex);
} else {
try {
Mapplication.stopservice (Intent);
Thread.Sleep (2000);
} catch (Interruptedexception e) {
E.printstacktrace ();
}
}

After exiting the program, start applying the first loginactivity
Intent = new Intent (mapplication, mainactivity.class);
Pendingintent restartintent =
Pendingintent.getactivity (Mapplication,
0,
Intent
Intent.flag_activity_new_task);
Alarmmanager Alarmmanager = (Alarmmanager)
Mapplication.getsystemservice (Context.alarm_service);
Alarmmanager.set ( ALARMMANAGER.RTC,
System.currenttimemillis () + 1000,
Restartintent);

Mapplication.exit ();
}

/**
* Exception Handling function
* @param ex
* @return
*/
Private Boolean handleexception (Throwable ex) {
if (ex = = null) {
return false;
}

Restart a thread to display exception information
New Thread () {
@Override
public void Run () {
Looper.prepare ();
Showexceptiontoast ();
Looper.loop ();
}
}.start ();
return true;
}

/**
* Show exception toast, confirm restart app
*/
private void Showexceptiontoast () {
Toast toast = Toast.maketext (Mapplication,
"Very sorry," CEPM360 "has stopped execution, is about to restart", Toast.length_short);
Set Center display
Toast.setgravity (gravity.center, 0, 0);

LinearLayout toastlayout = (linearlayout) Toast.getview ();
Toastlayout.setlayoutdirection (linearlayout.horizontal);

ImageView image = new ImageView (mapplication);
Image.setimageresource (r.drawable.exception_picture);
Toastlayout.addview (image, 0);

Toast.setview (toastlayout);
Toast.show ();
}
}

Above is a self-defined uncaught exception handler. To make it work, you need to cooperate with application, which by default does not require you to manually implement or instantiate a Application object. But you define the activity that you want to finish in the unhandled exception handling. However, there is no corresponding task-related API in application, there is no way to get the current application in the task of all the activity, so we need to implement a application class, and maintain a list of activity, When an activity is started, it is added to the list, and when an uncaught exception occurs, the entire activity is removed one by one.

public class MyApplication extends application {

Activity list to completely exit the app
Private list<activity> mactivities = new arraylist<activity> ();
Sharing data
Private map<string, object> mappshareddata = new hashmap<string, object> ();

@Override
public void OnCreate () {
Super.oncreate ();
Mycrashhandler.getinstance (this);
}

/**
* Get data that should be shared
* @return
*/
Public map<string, Object> Getappshareddata () {
return mappshareddata;
}

/**
* Add a shared map element
* @param map
*/
public void Addshareddata (map<string, object> Map) {
Mappshareddata.putall (map);
}

/**
* Add a shared element
* @param string
* @param Object
*/
public void Addshareddata (string string, Object object) {
Mappshareddata.put (String, object);
}

/**
* Get shared element values
* @param string
* @return
*/
Public Object GetValue (string string) {
return Mappshareddata.get (String);
}

/**
* When you start an activity, add it to the list
* @param activity
*/
public void addactivity (activity activity) {
Mactivities.add (activity);
}

/**
* Exit the App
*/
public void exit () {
Loop out of activity
try {
for (Activity activity:mactivities) {
if (activity! = NULL)
Activity.finish ();
}
} catch (Exception e) {
E.printstacktrace ();
} finally {
Finally exit the virtual machine
System.exit (0);
}
}

@Override
public void Onlowmemory () {
Super.onlowmemory ();
System.GC ();
}

}

The above Mappshareddata mapping table is a data share for the app, not the focus of this article. The key point here is that all of the exceptions are handled in the Uncaughtexception function in Mycrashhandler. Contains stop service and activity. After you send the restart broadcast, exit the virtual machine. It is also possible to use the following code:

Android.os.Process.killProcess (Android.os.Process.myPid ());

Self-defining uncaught exception handling for application

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.