Содержание
Во второй части статьи об необработанных исключениях немного расширим логику приложения: будем пробрасывать необработанное исключения далее чтобы стандартный обработчик обработал его, stacktrace исключения отсылается на указанный адрес и если приложение не может отослать данные, то автоматически выключается через 10 секунд.
Приступим к первому пункуту - добавим проброс необработанного исключения стандартному обработчику. Для этого в Вашем activity объявите экземпляр класса Thread.UncaughtExceptionHandler:
Thread.UncaughtExceptionHandler defaultExceptionHandler;
Затем в методе onCreate() Вашего activity сохраните обработчик исключений по умолчанию в эту переменную перед установкой нового обработчика:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);
// ...
}
А в обработчике необработанных исключений добавьте вызов метода uncaughtException() объекта defaultExceptionHandler:
defaultExceptionHandler.uncaughtException(t, e);
Файл activity целиком:
package com.seostella.catchcrashreport;
import android.app.Activity;
import android.os.Bundle;
public class CatchCrashReportActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler);
int a = 1;
a--;
int b = 10 / a;
}
Thread.UncaughtExceptionHandler defaultExceptionHandler;
Thread.UncaughtExceptionHandler uncaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
e.printStackTrace();
// do something
defaultExceptionHandler.uncaughtException(t, e);
}
};
}
Второй пункт - отсылка информации о исключении на сервер. Описывать непосредственно отсылку сообщения мы не будем так как работа с сетью выходит за границы этой статьи. Подготовим лишь объект для отсылки. Для этого измените метод uncaughtException() следующим образом:
@Override
public void uncaughtException(Thread t, Throwable e) {
e.printStackTrace();
// do something
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
e.printStackTrace(printWriter);
String stacktrace = result.toString();
printWriter.close();
// send stacktrace data
defaultExceptionHandler.uncaughtException(t, e);
}
Этим кодом мы создаем строковую переменную stacktrace с информацией об исключении.
И, наконец, автозавершение программы если она не завершилась сама через 10 секунд после исключения. Тут всё просто: в Ваш activity добавьте следующий метод:
public void startExitChecker(){
new Thread(){
private static final long WAIT_TIME = 10000;
private static final long SMALL_WAIT_TIME = 1000;
public void run(){
try{
long startTime = System.currentTimeMillis();
boolean forceClose = true;
while( System.currentTimeMillis() - startTime < WAIT_TIME ){
try {
Thread.sleep( SMALL_WAIT_TIME );
} catch (InterruptedException e) {
e.printStackTrace();
}
if( CatchCrashReportActivity.this == null ){
forceClose = false;
break;
}
}
if( forceClose ){
CatchCrashReportActivity.this.finish();
}
} catch( Exception e ){
}
}
}.start();
}
Вызов этого метода необходимо поместить в метод uncaughtException() перед вызовом обработчика исключений по умолчанию. То есть, метод uncaughtException() выглядит следующим образом:
@Override
public void uncaughtException(Thread t, Throwable e) {
e.printStackTrace();
// do something
final Writer result = new StringWriter();
final PrintWriter printWriter = new PrintWriter(result);
e.printStackTrace(printWriter);
String stacktrace = result.toString();
printWriter.close();
// send stacktrace data
startExitChecker();
defaultExceptionHandler.uncaughtException(t, e);
}
Приложение, демонстрирующее приведенные примеры можно скачать по следующей ссылке - Скачать CatchCrashReport.zip
< | Как отловить необработанные исключения (Force close) в Android |