ОБНОВЛЕНИЕ: см. "Принятое" решение ниже
Когда мое приложение создает необработанное исключение, а не просто завершает работу, я хотел бы сначала дать пользователю возможность отправить файл журнала. Я понимаю, что выполнять больше работы после получения случайного исключения рискованно, но, эй, хуже всего то, что приложение перестает работать, а файл журнала не отправляется. Это оказалось сложнее, чем я ожидал :)
Что работает: (1) перехват неперехваченного исключения, (2) извлечение информации журнала и запись в файл.
Что пока не работает: (3) начало действия по отправке электронной почты. В конце концов, у меня будет еще одно действие, чтобы спросить разрешения пользователя. Если у меня работает электронная почта, я не ожидаю особых проблем для другого.
Суть проблемы в том, что необработанное исключение попадает в мой класс Application. Поскольку это не Activity, не очевидно, как начать действие с Intent.ACTION_SEND. То есть обычно для начала действия вызывается startActivity и возобновляется с onActivityResult. Эти методы поддерживаются Activity, но не Application.
Есть предложения, как это сделать?
Вот несколько фрагментов кода в качестве руководства:
public class MyApplication extends Application
{
defaultUncaughtHandler = Thread.getDefaultUncaughtExceptionHandler();
public void onCreate ()
{
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
{
@Override
public void uncaughtException (Thread thread, Throwable e)
{
handleUncaughtException (thread, e);
}
});
}
private void handleUncaughtException (Thread thread, Throwable e)
{
String fullFileName = extractLogToFile(); // code not shown
// The following shows what I'd like, though it won't work like this.
Intent intent = new Intent (Intent.ACTION_SEND);
intent.setType ("plain/text");
intent.putExtra (Intent.EXTRA_EMAIL, new String[] {"me@mydomain.com"});
intent.putExtra (Intent.EXTRA_SUBJECT, "log file");
intent.putExtra (Intent.EXTRA_STREAM, Uri.parse ("file://" + fullFileName));
startActivityForResult (intent, ACTIVITY_REQUEST_SEND_LOG);
}
public void onActivityResult (int requestCode, int resultCode, Intent data)
{
if (requestCode == ACTIVITY_REQUEST_SEND_LOG)
System.exit(1);
}
}
источник
Ответы:
Вот полное решение (почти: я пропустил макет пользовательского интерфейса и обработку кнопок), полученное в результате множества экспериментов и различных сообщений других людей, связанных с проблемами, которые возникли на этом пути.
Вам нужно сделать следующее:
А теперь подробности:
(1 и 2) Обработка uncaughtException, начало отправки журнала активности:
(3) Извлечь журнал (я поместил это в свое действие SendLog):
(4) Запустите приложение электронной почты (также в моем действии SendLog):
(3 и 4) Вот как выглядит SendLog (хотя вам придется добавить пользовательский интерфейс):
(5) Манифест:
(6) Настройка Proguard:
В project.properties измените строку конфигурации. Вы должны указать «оптимизировать», иначе Proguard не будет удалять вызовы Log.v () и Log.d ().
В proguard-project.txt добавьте следующее. Это говорит Proguard предполагать, что Log.v и Log.d не имеют побочных эффектов (хотя они и есть, поскольку они записывают в журналы) и, таким образом, могут быть удалены во время оптимизации:
Это оно! Если у вас есть предложения по улучшению этого, пожалуйста, дайте мне знать, и я могу обновить это.
источник
Сегодня существует множество инструментов для перепечатки сбоев, с которыми это легко сделать.
crashlytics - бесплатный инструмент для отчетов о сбоях , но с базовыми отчетами. Преимущества: бесплатно.
Gryphonet - более продвинутый инструмент отчетности, требует некоторой платы. Преимущества: Легкое воссоздание сбоев, ANR, медлительности ...
Если вы частный разработчик, я бы посоветовал Crashlytics, но если это большая организация, я бы выбрал Gryphonet.
Удачи!
источник
Попробуйте вместо этого использовать ACRA - он обрабатывает отправку трассировки стека, а также множество другой полезной отладочной информации на ваш сервер или в настроенный вами документ Google Docs.
https://github.com/ACRA/acra
источник
Ответ @ PeriHartman хорошо работает, когда поток пользовательского интерфейса выдает неперехваченное исключение. Я сделал некоторые улучшения, когда неперехваченное исключение генерируется потоком, отличным от пользовательского интерфейса.
источник
Красиво объяснено. Но одно наблюдение здесь: вместо записи в файл с помощью File Writer и Streaming я напрямую использовал параметр logcat -f. Вот код
Это помогло мне очистить последнюю информацию о буфере. Использование потоковой передачи файлов дало мне одну проблему, заключающуюся в том, что не удалялись последние журналы из буфера. Но в любом случае это было действительно полезное руководство. Спасибо.
источник
Обработка неперехваченных исключений: как объяснил @gilm, просто сделайте это (kotlin):
Надеюсь, это поможет, у меня сработало .. (: y). В моем случае я использовал библиотеку com.microsoft.appcenter.crashes.Crashes для отслеживания ошибок.
источник
Вы можете обрабатывать неперехваченные исключения с помощью библиотеки FireCrasher и выполнять восстановление из нее.
вы можете узнать больше о библиотеке в этой средней статье
источник