📜 ⬆️ ⬇️

Making the simplest error collector for Android

When developing an application, one inevitably encounters errors in the code and / or environment. And it is very sad when such errors are encountered not on a test phone / emulator, but among live users. Even sadder if this is not your friend, a beta tester and no one can really explain what happened and where.

Usually, if the Android application suddenly drops, it offers to send an error report, where you will find detailed stack trace and version information for your application. Unfortunately, users do not always click the “send report” button, but for debugging applications or applications not from the market, such functionality is completely unavailable.

What to do? To the aid comes the ability of the Java language to handle exceptions (Exceptions), including those not caught (unhandled).
')


The Thread class has a static setDefaultUncaughtExceptionHandler method. This method allows you to set your own class handler for uncaught exceptions. The class handler must implement the Thread.UncaughtExceptionHandler interface. The handler frame might look something like this:
public class TryMe implements Thread.UncaughtExceptionHandler { @Override public void uncaughtException(Thread thread, Throwable throwable) { Log.d("TryMe", "Something wrong happened!"); } } 

The only method accepts a Thread at the input — the stream in which the exception occurred, and Throwable — the exception itself. The above implementation simply logs a message without any details ... Let's try to use ...
 public class MainActivity extends MapActivity { @Override public void onCreate(Bundle savedInstanceState) { Thread.setDefaultUncaughtExceptionHandler(new TryMe()); Integer a=1; if(true) a=null; int x = 6; x=x/a; // Exception here! } } 

After running the above code, we (hooray!) Will receive a message in the log ... and a black screen. Having installed our own handler, we removed the regular handler of the Android OS and now we are no longer offered to close the application.

We fix the situation
 public class TryMe implements Thread.UncaughtExceptionHandler { Thread.UncaughtExceptionHandler oldHandler; public TryMe() { oldHandler = Thread.getDefaultUncaughtExceptionHandler(); //     } @Override public void uncaughtException(Thread thread, Throwable throwable) { Log.d("TryMe", "Something wrong happened!"); if(oldHandler != null) //    ... oldHandler.uncaughtException(thread, throwable); // ...  } } 

Now we see both the message in the log and the usual system message.

It is inconvenient to install a handler in Activity. Although it will be installed in all the threads, the Activity can be several and several start. And there may be services ... In this case, it is best to install a handler when the application is initialized. Like this:
 public class MyApplication extends Application { @Override public void onCreate() { Thread.setDefaultUncaughtExceptionHandler(new TryMe()); super.onCreate(); } } 

At the same time, you need to remember to register a new application class in the manifest. Like this:
 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="my.package"> <application android:name="MyApplication" ... 

Now when you start the application (no matter what component), an exception handler will be installed.

Of course, displaying a message in the log is not serious. Need to collect more information. What version of the application? What exception is not processed? What other exception led to the fatal release? In which stream? What was the stack? All this information can be obtained. The code of the simplest exception handler receives and saves all the above information on the SD card on GitHub .

This implementation saves the information about the unhandled exception to a file on the SD card in the /Android/data/your.app.package.name/files/ folder ( as the Dev Guide tells ) in files of the form stacktrace-dd-MM-yy.txt. To work in the application manifest requires permission WRITE_EXTERNAL_STORAGE.

Naturally, this is not the only such solution.

Flurry - analytics for mobile applications, contains its error handler. ACRA is a library for Android, collects data about errors and posts them on GoogleDocs. Android-remote-stacktrace is a similar library that sends data to a custom receiver script. You can also get a lot of useful information on StackOverflow.

Source: https://habr.com/ru/post/129582/


All Articles