Зміст
У другій частині статті про необроблені винятки в Android трохи розширимо логіку програми: будемо прокидати необроблене виключення далі щоб стандартний обробник обробив його, 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
< | Як відловити необроблені виключення в Android |