Имя: Пароль:
IT
Мобильный мир
Повышение устойчивости приложения. Стратегия обработки ошибок
,
0 Волшебник
 
модератор
27.02.17
20:51
Программирую на Java под Android. И есть очень нехорошее свойство, что при малейшей нештатной ситуации программа закрывается (вылетает). Постоянно приходится добавлять try...catch (Попытка...Исключение), чтобы функция нормально отработала. Дошло уже до автоматизма, что пишу

public void f() {
try {
   здесь тело функции
} catch (Exception e) {
   Log.e(TAG, e.getMessage());
   e.printStackTrace();
}
}

Есть ли способ не уродовать каждую функцию, а сделать какую-то глобальную обработку ошибок?

Кроме того, не понимаю, зачем создавать собственный класс исключений? Ведь тогда моя ловушка может что-то не словить и нафиг она нужна?

Перед обращением к методу любого объекта надо проверять его на null, иначе выскакивает NullPointerException? Это вообще нормально?
1 Волшебник
 
модератор
28.02.17
12:27
Никто не знает?
2 Вафель
 
28.02.17
12:31
Про исключения: типизированные или нет - эт одревний холивар
3 Вафель
 
28.02.17
12:32
мне кажется к каждому случаю вылета нужно подходить отдельно
4 Вафель
 
28.02.17
12:35
про null. Переходи на котлин, там с этим попроще
5 Вафель
 
28.02.17
12:48
про котлин и null safety
http://kotlinlang.org/docs/reference/null-safety.html
6 Волшебник
 
модератор
28.02.17
12:48
(4) Да, я нашёл этого урода, который изобрёл Null Pointer
https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions

Поубывал бы...
7 Вафель
 
28.02.17
12:48
мне кажется это одна из главных причин почему котлин вообще запилили
8 Naf2017
 
28.02.17
12:50
>>Перед обращением к методу любого объекта надо проверять его на null, иначе выскакивает NullPointerException

а в 1С разве не так, когда объект=Неопределено?
9 Вафель
 
28.02.17
12:51
(8) если у тебя например типизированная колока, то ты не сможешь туда неопределено положить
10 Tateossian
 
28.02.17
12:52
(0) В нетбинс есть даже функция автоподстановки глобального логгера. Вот в Андроид студио ее нет, но ты ее можешь сделать сам. Или как вариант объявляю каждую функцию Throwable с пробросом в класс-обрабочтик ошибок.
11 Tateossian
 
28.02.17
12:54
(1) В Джаве сборщик мусора удаляет все из хеап, если ссылки null, поэтому явно надо проверять на null.

Для интерпретируемых языков - это нормально, хотя и неудобно.
12 Волшебник
 
модератор
28.02.17
16:58
Нашёл полезные статьи
https://habrahabr.ru/company/mailru/blog/322416/
и продолжение https://habrahabr.ru/company/mailru/blog/322804/
13 Garykom
 
гуру
28.02.17
18:06
1. Трайкатчить это плохо
2. 1С это зло (слишком расслабляет) для нормального программирования с предусматриванием всевозможных ситуаций чтобы штатно их отработать без ошибки.
3. Проверка на null это нормально, потому что по концепции ООП ты не знаешь что тебе передали, еще тип тоже проверять так то надо.
14 Волшебник
 
модератор
28.02.17
18:09
(13) по концепции ООП, реализованной в Java, типы вполне известны, но вот единственное уродливое значение null является любым типом
15 Garykom
 
гуру
28.02.17
18:09
А способ кстати есть чтобы писать удобно ))
Это придумать (и написать) свою "мобильную платформу" ну или взять какую то готовую.
16 Garykom
 
гуру
28.02.17
18:13
(14) Там есть засада с приведениями типов, к примеру
string b;
double a = (int)b;
17 Вафель
 
28.02.17
18:17
(16) разве так можно в джаве?
18 Волшебник
 
модератор
28.02.17
18:21
ещё полезная статья https://habrahabr.ru/post/221243/
в ней упоминается некие "null-аннотации"
Это что-то типа @Nullable, @NonNull и @CheckResult
Пока ещё мало ими пользовался.
19 Asmody
 
28.02.17
19:12
(0) Классы исключений нужны чтобы разные типы исключений обрабатывать по-разному. Например, если у тебя ошибка IO, то можно попытаться что-то сделать с файлом, а если деление на ноль, то это другая ситуация.
20 Asmody
 
28.02.17
19:20
В java 8 появился "привет из Scala" – класс Optional (который, на самом деле, монада Maybe из Haskell). Он инкапсулирет проверку на nullpointer.
21 Волшебник
 
модератор
28.02.17
19:41
(20) О, интересно
22 Волшебник
 
модератор
28.02.17
19:42
(20) монада Maybe очень понравится девушкам-программистам. Надо рассказать жёнам ;)
23 Asmody
 
28.02.17
19:44
Только под android java 8 не поддерживается.
24 Asmody
 
28.02.17
19:45
(22) Гланое, монаду с мандой не перепутать, а так всё нормально.
25 Волшебник
 
модератор
28.02.17
19:51
(23) почитал про Optional https://habrahabr.ru/post/225641/
Что-то он меня не впечатлил. Пустые ссылки у себя я уже реализовал. В объектах "Справочник" и "Документ" есть метод isEmpty() (аналог 1с Пустая()). Можно ещё дополнить объекты "Справочник" и "Документ" всей этой галиматьёй из Optional.
И что-то не радует меня натыкивать кругом это Optional<MyClass>...

В любом случае получается, что нужно что-то натыкивать:
1) или проверки на null и try-catch
2) или optional,
3) или null-аннотации.
А может всё сразу натыкать?
26 Asmody
 
28.02.17
19:59
(25) Выбора не много:
Otional ты не воткнешь. См.(23);
try catch дорогое удовольствие;
остается только проверять if'ами.
Аннотации - они больше для IDE и компилятора.
27 Волшебник
 
модератор
28.02.17
20:04
(26) fucking java... fucking android...
28 Asmody
 
28.02.17
20:08
(27) В андроиде, оказывается, много полезных аннотаций http://developer.alexanderklimov.ru/android/studio/support-annotations.php
29 Asmody
 
28.02.17
20:14
Вот прямо в тему https://habrahabr.ru/post/237843/
30 Волшебник
 
модератор
28.02.17
20:20
(28) Да-да. Я уже воспользовался аннотацией @Deprecated для собственных классов. Очень полезная штучка для рефакторинга. Перед непосредственным разрушением программы
1) ставишь аннотацию @Deprecated перед методом/классом/переменной, которые планируешь уничтожить/переместить.
2) делаешь Find Usages (Alt-F7). Все вызовы становятся зачёркнутыми. Справа в модулях появляются жёлтые метки.
3) проводишь рефакторинг, при котором код можно копировать и часто запускать. Добиваешься чистого кода. В итоге класс/метод/переменная, который пометил @Deprecated, должны стать серыми. Но подсветка может глючить, поэтому делаешь Find Usages и убеждаешься, что нет ссылок.
4) комментируешь старую сущность, делаешь контрольный запуск с прогоном тестов и удаляешь нахрен. Всё. Рефакторинг закончен.
31 Garykom
 
гуру
28.02.17
20:33
(30) Кстати когда 1С то до этого дойдет вместо этих "Удалить..." ))
32 Garykom
 
гуру
28.02.17
20:33
(31)+ в уже ненужных метаданных
33 Garykom
 
гуру
28.02.17
20:47
(17) Нельзя конечно, просто пример привел, к примеру

String b = null;
double a = Integer.parseInt(b);

Прекрасно компилится и замечательно падает, ибо проверки на null нету...

А даже если и проверил на нулл то будь добр еще или проверь валидность внутри строки для преобразования в число ну или

String b = null;
double a;
try {
  a = Integer.parseInt(b);
} catch (NumberFormatException e) {
  System.out.println(e.toString());
}
34 Волшебник
 
модератор
28.02.17
20:55
(33) Я решил эту проблему просто: не пользуюсь Integer.
Мне хватает int
35 Xapac
 
28.02.17
21:03
(0)Это чё миста на андроилд будет?
36 Волшебник
 
модератор
28.02.17
21:06
(35) Уже есть клиенты для форума на Андроиде. Ниша уже занята.
37 dubraver
 
28.02.17
21:07
Чтобы ловить необработаные исключения, я делал так:

1. Создаем класс ExceptionHandler который реализует интерфейс: java.lang.Thread.UncaughtExceptionHandler

2.В методе onCreate каждой активности добавляем строчку:
Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(this));

3.Для отображения ошибки рисуем свой layout activity_error.xml, с отображением stacktrace и кнопкой отправки разработчику.

Гайд:
https://github.com/hardik-trivedi/ForceClose
38 Волшебник
 
модератор
28.02.17
21:16
(37) Огромнейшее спасибо! Это громадный шаг в правильном направлении!
Ошибка? Это не ошибка, это системная функция.