Java-кодинг для Android: обработка исключений

Программирование для Android: обработка исключений JavaПроблема

Язык Java имеет четко определенный механизм обработки исключений, но требу­ется некоторое время, чтобы научиться эффективно его использовать, не разочаро­вывая ни пользователей, ни специалистов технической поддержки.

 



Решение

Язык Java предлагает иерархию исключений, которая обеспечивает значительную гибкость при правильном использовании. Android предлагает несколько механизмов, включая диалоговые окна и тосты, для уведомления пользователя об ошибках. Разработчик приложений для платформы Android должен ознакомиться с этими ме­ханизмами и научиться эффективно их использовать.

 

Обсуждение

В языке Java существуют две категории исключений (которые фактически являют­ся производными от класса Throwable, родительского класса по отношению к классу Exception): проверяемые и непроверяемые. Авторы платформы Java Standard Edition, очевидно, хотели заставить программистов признать тот факт, что что-то можно об­наружить во время компиляции, а что-то нет. Например, если вы устанавливаете настольное приложение на большое количество персональных компьютеров, скорее всего, диск на некоторых из них будет почти заполненным, и попытка сохранить дан­ные на них может завершиться неудачно. Между тем на других компьютерах файл, зависящий от приложения, может отсутствовать не из-за ошибки программиста, а из-за ошибки пользователя, случайности файловой системы, разрыва кабеля или чего-то еще. Таким образом, категория IOException была создана как проверяемое исключение, которое программист обязан проверить либо с помощью инструкции try-catch внутри метода, использующего файл, либо с помощью инструкции throws в определении метода. Общее правило, которое знают все хорошо обученные разра­ботчики на языке Java, формулируется следующим образом.

Класс Throwable является корнем иерархии генерируемых исключений. Класс

Exception и все его подклассы, за исключением класса RuntimeException или

всех его подклассов, являются проверяемыми исключениями. Все остальные

являются непроверяемыми.

Это означает, что класс Error и все его подклассы являются непроверяемы­ми (рис. 1). Например, если вы получаете объект класса VMError, это означает, что во время выполнения возникла ошибка. В качестве прикладного программис­та вы ничего не можете сделать. К подклассам класса RuntimeException относит­ся, в частности, класс с очень длинным именем ArraylndexOutOfBoundsException.

Его дружественные классы являются непроверяемыми, потому что ответственность за эти исключения во время разработки и их тестирование лежит на вас.

Иерархия генерируемых исключений

Рис. 1. Иерархия генерируемых исключений

 

Где перехватывать исключения

Использование проверяемых исключений привело к тому, что многие ранние разработчики программ на языке Java писали код, который был испещрен блоками try-catch, отчасти потому, что важность использования инструкции throws недо­статочно подчеркивалась в некоторых учебных программах и книгах. Поскольку сам язык Java перенес акцент на корпоративную работу и появились новые каркасы, такие как Spring, Hibernate и JPA, которые делают упор на использовании непроверяемых исключений, эта первоначальная позиция изменилась. В настоящее время общепризнано, что перехватывать исключения желательно как можно ближе к поль­зователю. Не следует пытаться выполнять обработку ошибок в коде, предназначен­ном для повторного использования, — в библиотеках и даже многократно запуска­емых приложениях. Он может выполнить лишь трансляцию исключения (exception translation), т.е. превращение исключения, специфичного для технологии (и обычно проверяемого), в обобщенное непроверяемое исключение. Образец показан в при­мере 1.

Пример 1. Трансляция исключения

public class ExceptionTranslation {
    public String readTheFile(String f) {
        try (BufferedReader is = new BufferedReader(new FileReader(f))) {
            String line = is.readLine();
            return line;
        } catch (FileNotFoundException fnf) {
            throw new RuntimeException("Could not open file " + f, fnf);
        } catch (IOException ex) {
            throw new RuntimeException("Problem reading file " + f, ex);
        }
    }
}

Обратите внимание, что до появления версии Java 7, для того чтобы закрыть файл, вам пришлось бы написать явную инструкцию finally:

    } finally {
        if (is != null) {
            try {
                is.close();
            } catch(IOException grr) {
                throw new RuntimeException("Error on close of " + f, grr);
            }
        }
    }
}

Подчеркнем также, что использование проверяемых исключений загроможда­ет даже этот код: функция is.close() практически никогда не может дать сбой, но поскольку вы хотите включить ее в блок finally (чтобы убедиться, что файл был открыт, но что-то пошло не так), необходимо предусмотреть дополнительную внешнюю инструкцию try-catch. Таким образом, проверяемые исключения (чаще все­го) раздражают, и их следует избегать в новых интерфейсах API и заменять непрове­ряемыми исключениями, если это необходимо.

Существует противоположная точка зрения, поддерживаемая официаль­ным сайтом Oracle и другими. В комментарии на веб-сайте читатель Ал Саттон (А1 Sutton) указывает следующее.

Существуют проверяемые исключения, заставляющие разработчиков при­знать, что может возникнуть ошибочное условие и что они подумали о том, как с ним справиться. Во многих случаях, помимо записи в журнале и вос­становления, сделать можно очень мало, но разработчик все же признает, что он предусмотрел обработку этого типа ошибок. В приведенном примере... код останавливает вызовы метода, если файла не существует (и, возможно, его не­обходимо повторно загрузить), или возникает проблема с его чтением (и, сле­довательно, файл существует, но не читается). Они представляют собой два разных типа ошибок.

Платформа Android, желая быть верной интерфейсу Java API, имеет несколько та­ких проверяемых исключений (включая те, которые показаны в примере), поэтому их следует обрабатывать одинаково.

 

Что делать с исключениями?

Исключения почти всегда должны выдавать сообщения. Когда я вижу код, ко­торый перехватывает исключения и ничего с ними не делает, я прихожу в отчая­ние. Ну хотя бы сообщите об их появлении (но не делайте одновременно запись в журнале и трансляцию или повторное генерирование!). Все исключения должны, как следует из названия, служить индикаторами исключительных условий. Поскольку на устройстве Android отсутствует системный администратор или оператор консоли, сообщать об исключительных условиях необходимо пользователю.

Необходимо подумать о том, как сообщать об исключениях: с помощью диалого­вых окон или тостов. Обработка исключений на мобильном устройстве отличается от обработки на настольном компьютере. Пользователь может управлять автомоби­лем или другим оборудованием, общаться с людьми и т.д., поэтому вы не должны предполагать, что он полностью сконцентрирован на приложении.

Я знаю, что большинство примеров, даже в этой книге, используют тосты, потому что они требуют меньше кодирования, чем диалоговые окна. Но помните, что тост отображается на экране только в течение нескольких секунд; моргнув, вы можете его пропустить. Если пользователю необходимо что-то сделать, чтобы устранить пробле­му, необходимо использовать диалоговые окна.

Тосты просто всплывают, а затем забываются. Диалоговые окна требуют от поль­зователя либо подтверждения исключения, либо разрешения на продолжение рабо­ты, которое иногда может стоить денег (например, подключение доступа к Интерне­ту для запуска приложения, которому необходимо загрузить фрагменты карты).

Используйте тосты, чтобы выводить на экран неважную информацию; для отображения важной информации и получения подтверждения ис­пользуйте диалоговые окна.

Вас заинтересует / Intresting for you:

Распространенные заблуждения о...
Распространенные заблуждения о... 1139 просмотров Ирина Светлова Thu, 21 Jun 2018, 18:35:12
Выбор среды для разработки код...
Выбор среды для разработки код... 1237 просмотров Rasen Fasenger Sun, 10 Jun 2018, 14:21:35
Аплеты Java и Интернет
Аплеты Java и Интернет 1118 просмотров Ирина Светлова Sat, 09 Jun 2018, 10:17:34
Как выполнить / скомпилировать...
Как выполнить / скомпилировать... 2104 просмотров Rasen Fasenger Thu, 21 Jun 2018, 18:32:00

Войдите чтобы комментировать

apv аватар
apv ответил в теме #9359 22 фев 2019 09:13
Отличный гайд! Спасибо :)