Я создал класс BaseActivity extends AppCompatActivity
, из которого наследуются все мои Activites в приложении для Android.Регистрация необработанных исключений в Android Activity
В этом классе я собирался поймать все необработанные исключения, поэтому я могу записать их в локальную базу данных SQLite для последующей проверки/отправки на удаленный сервер.
Ниже я прилагаю весь код класса:
public class BaseActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Thread.UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
Log.e("Uncaught Exception", paramThrowable.getMessage());
logError(paramThrowable);
defaultHandler.uncaughtException(paramThread, paramThrowable);
}
});
}
private void logError(final Throwable paramThrowable){
try {
ApplicationError error = new ApplicationError();
String stackTrace = "";
for (int i = 0; i < paramThrowable.getStackTrace().length; i++) {
stackTrace += paramThrowable.getStackTrace()[i].toString() + "\n";
}
Throwable tmp = paramThrowable;
int j = 0;
while ((tmp = tmp.getCause()) != null && j < 5) {
j++;
stackTrace += "Coused by:\n";
for (int i = 0; i < tmp.getStackTrace().length; i++) {
stackTrace += tmp.getStackTrace()[i].toString() + "\n";
}
}
Log.e("Saving error...", "");
String deviceInfo = "";
deviceInfo += "OS version: " + System.getProperty("os.version") + "\n";
deviceInfo += "API level: " + Build.VERSION.SDK_INT + "\n";
deviceInfo += "Manufacturer: " + Build.MANUFACTURER + "\n";
deviceInfo += "Device: " + Build.DEVICE + "\n";
deviceInfo += "Model: " + Build.MODEL + "\n";
deviceInfo += "Product: " + Build.PRODUCT + "\n";
error.mDeviceInfo = deviceInfo;
error.mErrorMessage = paramThrowable.getMessage();
error.mStackTrace = stackTrace;
error.save();
Log.e("Saved error:", error.mErrorMessage + "\n" + error.mStackTrace);
}catch(Exception e){
}
}
}
Для уточнения:ApplicationError
только модель класса, который обрабатывает сохранение в базе данных с помощью DBFlow
.
Проблема
Каждый раз, когда возникает необработанное исключение (не имеет значения, что это такое) в деятельности двух странные вещи происходят:
- Метод
logError()
называется более чем один раз, иногда даже 8-10 раз. Глядя на журналы, я вижу, что у них почти такая же метка времени. - сообщение «XXX Применение остановилось» отображается на экране устройства (и это хорошо), но после его закрытия приложения повешен, и мне нужно принудительно остановить с экрана настройки приложения.
Может кто-нибудь помочь мне с этим? Или есть лучший подход к проблеме?
Вы знаете, что есть рамки, которые будут делать это для вас не так ли? Crashlytics, Acra, Bugsense и т. Д. –
Поддерживает ли кто-нибудь из них отправку ошибки в пользовательское серверное приложение во время синхронизации?Мне нужно уточнить, что мне нужно сохранить ошибку в базе данных для последующей синхронизации, потому что это требование, чтобы приложение регистрировало ошибки для последующей синхронизации даже в автономном режиме. – jdabrowski
Все они кэшируют ошибки, которые случаются offlie и отправляют их, когда есть активное сетевое подключение. ACRA (и, возможно, другие, я не знаю) будет поддерживать отправку на ваш собственный сервер, я считаю. –