Just as Paulo Rodrigues quoted, Android, more specifically the JVM, allows you to register a Handler
to Exception's
untreated.
And, I believe, any library that allows error reporting uses the same technique.
Treating uncaught Exception's
The simplest and perhaps most organized way to do this is by using the Application
class. Where at the beginning of the application, in the onCreate
method, you register Handler
.
An example I use a lot:
public class Application extends android.app.Application implements Thread.UncaughtExceptionHandler {
private Thread.UncaughtExceptionHandler mDefaultExceptionHandler;
@Override
public void onCreate() {
super.onCreate();
mDefaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(this);
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
// Aqui você pode tratar a Exception...
mDefaultExceptionHandler.uncaughtException(thread, ex);
}
}
Okay, with just that, it does not answer every question. Thread.UncaughtExceptionHandler
answers only your first question.
With Thread.UncaughtExceptionHandler
I think it's possible to answer the last two, but you need a little more code.
Writing to file
For the second question, I'm sure it's possible, because some of the treatments I do in some app's are to write to a file the error log, but I usually use a Thread
to do this. >
A simple way:
@Override
public void uncaughtException(Thread thread, final Throwable ex) {
new Thread(){
@Override
public void run() {
File file = new File("NOME_DO_ARQUIVO");
FileWriter writer = null;
try {
writer = new FileWriter(file);
writer.write(throwableToString(ex));
} catch (IOException e) {
} finally {
close(writer);
}
}
}.start();
}
private String throwableToString(Throwable t) {
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter, false);
t.printStackTrace(printWriter);
printWriter.flush();
stringWriter.flush();
return stringWriter.toString();
}
Saving Exception in SQLite
Yes, it is possible. I never did this, but in line with this project / a> is possible.
A leaner example would be:
@Override
public void uncaughtException(Thread thread, final Throwable ex) {
new Thread(){
@Override
public void run() {
SQLiteDatabase db = new SeuSQLiteOpenHelper(Application.this).getWritableDatabase();
String sql = "insert into exceptions(exception, created_at) values (?, ?)";
Object args[] = {
throwableToString(ex),
System.currentTimeMillis() / 1000
};
try {
db.execSQL(sql, args);
} catch(Exception e){
} finally {
db.close();
}
}
}.start();
}
And as alerted by Fernando, the declaration of class Application
in AndroidManifest was missing:
<application
<!-- Demais atributos -->
android:name=".application.Application" />