Java lang runtimeexception ошибка андроид
Обновлено: 19.09.2024
Я пытался запустить пример кода При запуске приложения в эмуляторе Android 1.5 , я получил эти ошибки. У любого есть какой-то намек.
ошибка от LogCat:
Edit Эта ошибка случается с большинством новичков, дело в том, что вы должны добавить все свои действия в файл манифеста.
это проблема вашего намерения.
пожалуйста, добавьте свой Activity в своем AndroidManifest.xml .
когда вы хотите сделать новую операцию, вы должны зарегистрировать его в AndroidManifest.xml .
в моем случае я забыл добавить библиотеку карт google
кроме того, убедитесь, что вы не пропустили предыдущую точку перед путем активности
возможно, вы пытаетесь найти смотреть перед onCreate() , что является неверным.
Это также происходит из-за этой проблемы. Я снял флажки с банок, которые нужно было экспортировать в apk, и то же самое произошло. Пожалуйста, отметьте банки, которые ваше приложение должно запустить.
- использование ActionBarSherlock в качестве библиотеки
- использование android-поддержка-v4-r7-googlemaps.jar в библиотеке ActionBarSherlock, чтобы я мог использовать "фрагмент карты" в моем основном проекте
- добавил Jar в путь сборки моего основного проекта
- включил <uses-library android:name="com.google.android.maps" /> в манифестах как проекта библиотеки, так и моего первичный проект (это может быть не нужно в библиотеке?)
- манифест в основном проекте имел правильное определение активности и все соответствующие свойства
- у меня не было абстрактной активности или каких-либо других gotchas, которые я видел в Stack Overflow, относящихся к этой проблеме.
- это повлияло только на новую установку приложения на мое устройство. Каждый раз, когда приложение устанавливается в первый раз, я получаю ошибку, предшествующую нескольким "предупреждениям": не удается разрешить суперкласс FragmentActivity
- эти предупреждения прослеживаются до библиотеки ActionBarSherlock
- приложение будет принудительно закрыть и аварии.
- если я сразу же перестроил и перераспределил приложение, оно отлично работало.
- единственный раз он разбился на совершенно новой установки. Если я удалил приложение, построил и развернул его снова из Eclipse, он рухнет. Сборка / развертывание во второй раз, это будет работать нормально.
- в проекте библиотеки ActionBarSherlock я добавил android-support-v4-r7-googlemaps.Jar в путь сборки
этот шаг сам по себе не исправил проблему
Как только jar был добавлен в путь сборки, у меня был измените порядок на вкладке путь сборки Java > порядок и экспорт-я установил JAR на первый элемент в списке (он был последним после элементов /src и /gen).
затем я перестроил и передислоцировал приложение на свое устройство-он работал, как ожидалось, на новой установке. Просто чтобы быть уверенным, я удалил его снова 2-3 раза и переустановил - все еще работал, как ожидалось.
эта ошибка также может быть окончательным признаком глупой ошибки (например, когда я - я имею в виду, кашель, например, когда мой друг, который показал мне свой код однажды), где они пытаются выполнить код вне метода, такого как попытка сделать это:
вместо этого:
это может не иметь отношения к фактическому вопросу, но в моем случае я попытался реализовать Kotlin и оставил apply plugin: 'kotlin-android' . Ошибка произошла потому, что он не мог распознать MainActivity в качестве .файл КТ.
надеюсь, что это поможет кому-то.
Я избавился от этой проблемы путем удаления Bin и Gen папка из проекта (которая автоматически возвращается, когда проект будет построен), а затем очистка проекта из ->меню -> проект -> очистить.
спасибо.
в моем случае я не поставил setContentView(R.layout.main);
Если вы создаете новый класс не foget, чтобы установить это в on onCreate(Bundle savedInstanceState) метод.
Я сделал эту глупую ошибку несколько раз.
просто очистите свой рабочий проект или перезапустите eclipse. Затем запустите свой проект. это сработает.
для меня, моя строка пакет в AndroidManifest.xml было неверно (скопировано из учебника). Убедитесь, что строка пакета в этом файле совпадает с тем, где находится ваша основная деятельность, например
простой способ сделать это-открыть AndroidManifest.xml-файл на вкладке "манифест" и введите его в текстовое поле рядом с пакетом или используйте кнопку Обзор.
кроме того, строка пакета для моей деятельности была неправильной, например
Я (тупо) получил ту же ошибку несколько недель спустя, когда я переименовал свое имя пакета. Если вы сделаете это, убедитесь, что вы обновить тоже.
хорошо, я довольно опытный на iPhone, но новый для android. Я получил эту проблему, когда у меня было:
эта строка кода выше:
может быть, я лишен сна: P
Я недавно столкнулся с этим со свежей переустановкой Eclipse. Оказывается, мой уровень соответствия компилятора был установлен на Java 1.7, а проект требовал 1.6.
В Eclipse: Проект - > свойства - > компилятор Java - > соответствие JDK
получил эту проблему и исправил ее, установив свойство "режим запуска" действия.
еще одной причиной этой проблемы может быть отсутствие библиотеки.
перейдите в свойства - > Android и проверьте, что вы правильно добавляете библиотеки
У меня была та же проблема, но у меня была объявлена моя активность в файле манифеста с правильным именем.
моя проблема заключалась в том, что мне не нужно было импортировать сторонние библиотеки в папку "libs", и мне нужно было ссылаться на них в моем проекте (щелкните правой кнопкой мыши, Свойства, путь сборки Java, библиотеки, добавить Jar. ).
Это может произойти, если ваш класс активности находится внутри пакета по умолчанию. Я исправил это, переместив класс activity в новый пакет. и изменение манифеста.xml
до
после
это происходит со мной довольно часто при использовании NDK. Я обнаружил, что мне необходимо сделать "чистый" в Eclipse после каждого раза, когда я делаю ndk-build . Надеюсь, это поможет кому-нибудь:)
щелкните правой кнопкой мыши на проекте > свойства > android > и попробуйте с другой версией android ранее я делал с android 4.4, затем я перешел на android 4.3, и это сработало !
у меня была та же проблема (невозможно создать экземпляр Activity) :
первая причина :
Я обращался
до
таким образом, правильный способ сделать это, сначала откройте камеру, а затем доступ к параметрам.
вторая причина: объявите свою деятельность в файле манифеста
третья причина : Объявите разрешение камеры в файле манифеста.
надеюсь, что это помогает
в моем случае, я пытался вставить Facebook SDK и я был неправ идентификатор приложения; таким образом, ошибка выскакивает. В файле манифеста вы должны иметь соответствующие метаданные:
Если у вас установлена Android Studio 2.3.3 и Android Studio 3.0.0, то переключение между двумя программами для разработки вызовет эту ошибку. Это связано с тем, что существуют ситуации, когда классы, поддерживаемые в одной программе, не поддерживаются другой и наоборот. Важно поддерживать согласованность в том, какая версия Android Studio используется для разработки проекта.
Это случилось со мной, когда я пытался запустить Activity на 2.2, который использовал импорт из Honeycomb, недоступный в более старых версиях Android и не включенный в пакет поддержки v4.
Ваша новая деятельность добавить AndroidManifest.xml как ".NewActivity"
вы можете иметь некоторые ошибки в областях, таких как
поэтому мой совет-выполнить всю инициализацию в методе onCreate не непосредственно в Ваших полях
решите вот так
Это также может произойти, если у вас есть два проекта с одинаковым именем пакета, и вы запустили один из них перед другим, поэтому я думаю, что это смущает Eclipse. Для меня это произошло, когда я скопировал учебник Android в eclipse в том же рабочем пространстве и оставил имена пакетов одинаковыми, но добавил к нему ActionBarSherlock (ABS), например
Так что в моем AndroidManifest.xml-файл, как проект учебника, который был в моей рабочей области, так и скопированный проект учебника, оба имели в качестве пакета строка:
просто измените имя пакета путем рефакторинга (в eclipse щелкните правой кнопкой мыши на пакете на вкладке проводник пакетов > выберите рефрактор > выберите Переименовать. ) а затем изменить его в вашем AndroidManifest.xml-файл и в любом другом месте вам нужно (например, как все ваши .java-файлы)
также, если вы извлекаете что-то из intent другой деятельности с помощью getIntent в текущей деятельности и установка этих полученных данных перед/выше onCreate то это исключение.
например. если я получаю строку, как это
и поставить эту строку кода перед/выше onCreate то это исключение.
Я пытался запустить образец кода При запуске приложения в эмуляторе android 1.5 я получил эти ошибки. У любого есть какой-то намек.
ОШИБКА из LogCat:
Edit Эта ошибка происходит с большинством новичков, дело в том, что вы должны добавить все свои действия в файл манифеста.
ОТВЕТЫ
Ответ 1
Это проблема вашего намерения.
Пожалуйста, добавьте Activity в свой AndroidManifest.xml .
Если вы хотите создать новую активность, вы должны зарегистрировать ее в своем AndroidManifest.xml .
Ответ 2
В моем случае я забыл добавить библиотеку карт google
Кроме того, убедитесь, что перед прохождением пути вы не пропустили предыдущую точку.
Ответ 3
Возможно, вы пытаетесь найти представление до onCreate() , которое является неправильным.
Ответ 4
Ответ 5
Это также происходит из-за этой проблемы. Я снял флажки, которые нужно было экспортировать в apk, и это случилось. Пожалуйста, отметьте флажки, которые необходимо выполнить вашему приложению.
Ответ 6
Я тоже столкнулся с этой проблемой, но несколько иначе. Вот мой сценарий:
- Использование ActionBarSherlock в качестве библиотеки
- Использование android-support-v4-r7-googlemaps.jar в библиотеке ActionBarSherlock, чтобы я мог использовать "фрагмент карты" в своем основном проекте
- Добавлен банку в путь сборки моего основного проекта
- Включен <uses-library android:name="com.google.android.maps" /> в манифесты как проекта библиотеки, так и моего основного проекта (это может быть необязательно в библиотеке?)
- манифест в основном проекте имел правильное определение активности и все соответствующие свойства
- У меня не было абстрактного действия или каких-либо других ошибок, которые я видел при переполнении стека, относящихся к этой проблеме.
Однако я все еще сталкивался с ошибкой, описанной в исходном посте, и не мог заставить ее уйти. Однако проблема была несколько иной:
- Это повлияло только на новую установку приложения на мое устройство. Каждый раз, когда приложение установлено в первый раз, я получаю ошибку, предшествующую нескольким "предупреждениям": Не удается разрешить суперкласс FragmentActivity
- Эти предупреждения восходят к библиотеке ActionBarSherlock.
- Приложение будет принудительно закрываться и сбой.
- Если я немедленно перестроил и переустановил приложение, он работал нормально.
- Единственный раз, когда он разбился, был на совершенно новой установке. Если я удалю приложение, которое снова будет создано и развернуто из Eclipse, оно будет аварийно завершено. Создайте/разверните второй раз, он будет работать нормально.
Как я его исправил:
-
В проекте библиотеки ActionBarSherlock я добавил файл android-support-v4-r7-googlemaps.jar в путь сборки
Этот шаг не устранил проблему
Как только кувшин был добавлен в путь сборки, я изменил порядок на пути Java Build Path > Order and Export - я установил JAR в первый элемент в списке (это было последним после /src и/gen).
Затем я перестроил и перенастроил приложение на свое устройство - он работал, как ожидалось, на новой установке. Чтобы быть уверенным, я удалил его снова 2-3 раза и переустановил - все равно работал как ожидалось.
Ответ 7
Это может быть не актуально для актуального вопроса, но в моем случае я попытался реализовать Kotlin и оставил apply plugin: 'kotlin-android' . Ошибка произошла из-за того, что не удалось распознать MainActivity в файле .kt.
Надеюсь, что это поможет кому-то.
Ответ 8
Эта ошибка также может быть окончательным признаком глупой ошибки (например, когда я - я имею в виду, кашель, как когда мой друг, который однажды показал мне свой код), где они пытаются выполнить код вне метода, например, пытаться для этого:
Ответ 9
Ответ 10
В моем случае я не установил setContentView(R.layout.main);
Если вы создаете новый класс, не устанавливайте его в методе onCreate(Bundle savedInstanceState) .
Я сделал эту глупую ошибку несколько раз.
Ответ 11
Для меня моя строка пакета в AndroidManifest.xml была неправильной (скопирована из учебника). Убедитесь, что строка пакета в этом файле такая же, как и в вашем основном действии, например
Легкий способ сделать это - открыть файл AndroidManifest.xml на вкладке "Манифест" и ввести его в текстовое поле рядом с Пакетом или использовать кнопку "Обзор".
Кроме того, строка пакета для моей активности была неправильной, например.
Я (тупо) получил ту же ошибку спустя несколько недель, когда переименовал имя своего пакета. Если вы это сделаете, убедитесь, что вы также обновили файл AndroidManifest.xml .
Ответ 12
Просто очистите рабочий проект или перезапустите eclipse. Затем запустите проект. он будет работать.
Ответ 13
Хорошо, я довольно опытен на iPhone, но новичок в android. Я получил эту проблему, когда у меня было:
эта строка кода выше:
Может быть, я лишен сна: P
Ответ 14
Недавно я столкнулся с новой переустановкой Eclipse. Оказывается, мой уровень соответствия компиляторам установлен на Java 1.7, а для проекта требуется 1.6.
Ответ 15
Получил эту проблему и исправил ее, установив свойство "запуска" для этой операции.
Ответ 16
Другой причиной этой проблемы может быть недостающая библиотека.
Ответ 17
У меня была та же проблема, но у меня была заявленная активность в файле манифеста с правильным именем.
Моя проблема заключалась в том, что мне не пришлось импортировать библиотеки сторонних разработчиков в папку "libs", и мне нужно было ссылаться на них в моем proyect (правая кнопка мыши, свойства, путь сборки Java, библиотеки, добавление Jar. ).
Ответ 18
Это может произойти, если ваш класс активности находится в пакете по умолчанию. Я исправил это, переместив класс активности в новый пакет. и изменение manifest.xml
Ответ 19
Это происходит со мной довольно часто при использовании NDK. Я обнаружил, что мне нужно делать "Очистить" в Eclipse после каждого раза, когда я делаю ndk-build . Надеюсь, это поможет любому:)
Ответ 20
Эта ошибка также возникает, когда вы используете ActionBarActivity , но назначаете стиль AppCompat .
Ответ 21
Щелкните правой кнопкой мыши по проекту > properties > android > и попробуйте с другой версией андроида раньше, чем я занимался с android 4.4, затем я изменил на android 4.3, и он сработает!
Ответ 22
У меня была такая же проблема (не удалось создать экземпляр Activity):
Итак, правильный способ: сначала открыть камеру, а затем получить доступ к параметрам.
ВТОРАЯ причина: объявите свою активность в файле манифеста
ТРЕТЬЯ причина: Объявите разрешение камеры в файле манифеста.
Надеюсь, что это поможет
Ответ 23
В моем случае я пытался внедрить Facebook SDK, и у меня был неправильный Application ID; таким образом, ошибка всплывала. В вашем файле манифеста вы должны иметь соответствующие метаданные:
Ответ 24
Если у вас установлены Android Studio 2.3.3 и Android Studio 3.0.0, то переключение между двумя программами для разработки приведет к этой ошибке. Это связано с тем, что существуют ситуации, когда классы, поддерживаемые в одной программе, не поддерживаются другой и наоборот. Важно поддерживать согласованность, в которой версия Android Studio используется для разработки проекта.
Ответ 25
Как было предложено djjeck в комментарии в этом, я пропустил, чтобы добавить модификатор public для моего класса.
Это должно быть
Это может помочь некоторым вроде меня.
Ответ 26
Я испробовал все вышеупомянутое решение, но у меня ничего не получалось. после того, как я просто добавил extend активности вместо AppCompatActivity и работает нормально.
я не знаю, в чем дело.
Ответ 27
В моем случае я пытался инициализировать компоненты (UI) еще до onCreate для Activity.
Убедитесь, что компоненты пользовательского интерфейса инициализируются/связаны в onCreate метод после setContentView
NB: Это моя первая ошибка при изучении программирования на Android.
Ответ 28
Это случилось со мной, когда я попытался запустить Activity на 2.2, который использовал импорт из Honeycomb, недоступный в старых версиях Android и не включенный в пакет поддержки v4.
Ответ 29
Ваша новая активность добавляет AndroidManifest.xml как ".NewActivity"
Ответ 30
Вы должны убедиться, что все действия в вашем приложении правильно определены в файле AndroidManifest.xml.
Кроме того, если они начинаются с пути, убедитесь, что этот путь существует.
например. это не сработает:
Или еще лучше, не включайте пути при определении активности внутри манифеста. Введите только свое имя (с точкой перед ним).
Ошибка может возникать на Windows XP, из-за отсутствия нужных библиотек для Java.
Если Ваша проблема остаётся актуальной, запросите поддержку у TLauncher:
Скриншот ошибки NPE
Что это за ошибка java.lang.nullpointerexception
Номер строки с ошибкой
Что в отношении обычных пользователей, то появление ошибки java.lang.nullpointerexception у вас на ПК сигнализирует, что у вас что-то не так с функционалом пакетом Java на вашем компьютере, или что программа (или онлайн-приложение), работающие на Java, функционируют не совсем корректно. Если у вас возникает проблема, при которой Java апплет не загружен, рекомендую изучить материал по ссылке.
Как избавиться от ошибки java.lang.nullpointerexception? Способы борьбы с проблемой можно разделить на две основные группы – для пользователей и для разработчиков.
Для пользователей
Если вы встретились с данной ошибкой во время запуска (или работы) какой-либо программы (особенно это касается java.lang.nullpointerexception minecraft), то рекомендую выполнить следующее:
Java ошибка в Майнкрафт
Для разработчиков
Разработчикам стоит обратить внимание на следующее:
- Вызывайте методы equals(), а также equalsIgnoreCase() в известной строке литерала, и избегайте вызова данных методов у неизвестного объекта;
- Вместо toString() используйте valueOf() в ситуации, когда результат равнозначен;
- Применяйте null-безопасные библиотеки и методы;
- Старайтесь избегать возвращения null из метода, лучше возвращайте пустую коллекцию;
- Применяйте аннотации @Nullable и @NotNull;
- Не нужно лишней автоупаковки и автораспаковки в создаваемом вами коде, что приводит к созданию ненужных временных объектов;
- Регламентируйте границы на уровне СУБД;
- Правильно объявляйте соглашения о кодировании и выполняйте их.
try / catch / finally и исключения
Думаю, вряд ли найдется Java-разработчик, который хотя бы не слышал об исключениях. В принципе, они не являются исключительным свойством Java, есть они и в Delphi, и в C++. Однако в Java исключения используются особенно широко. И чаще всего с ними связано немало ошибок. Основная цель этой статьи – систематизация информации об исключениях, их обработке и т.п. А именно:
Исключение как явление
Что такое вообще исключение? Это сигнал о нестандартной – исключительной – ситуации. Ситуации могут быть самые различные – ожидаемые или нет, разной степени критичности. И относиться к этим ситуациям, естественно, приходится по-разному.
Как и всё в Java, исключения тоже представленны в виде классов. Корнем иерархии служит класс java.lang.Throwable , дословно – "бросаемый". Его прямыми наследниками являются java.lang.Exception и java.lang.Error, от которых и унаследованы все остальные исключения. И от которых рекомендуется наследовать собственные.
Хочу подчеркнуть, что исключения не есть нечто из ряда вон выходящее. Это нормальный механизм. Потому не стоит стараться избегать их использования любой ценой. И тем более не стоит стараться избегать исключений в конструкторах, к чему склонны разработчики, хорошо знакомые с С++. Ввиду наличия сборщика мусора утечек памяти в этом случае не будет. Разве что очень постараться, я имею в виду намеренно.
Теперь рассмотрим типы исключений ближе.
Классификация исключений
Как я уже упоминал, есть два "базовых" типа исключений – java.lang.Exception и java.lang.Error. Я бы сказал, что различаются степенью критичности. Не, разумеется, оба типа могут быть перехвачены, ибо перехватывается исключение начиная с уровня java.lang.Throwable . Это разделение скорее логическое. Если произошло что-то серьезное – не найден метод, который надо вызвать, закончилась память, переполнение стека, в общем, что-то, после чего восстановить нормальную работу уже вряд ли реально – это ошибка, java.lang.Error. Если продолжение работы теоретически возможно – это исключение, java.lang.Exception.
Поскольку исключения – точно такие же классы, в них можно включать и собственные переменные, и даже какую-то логику. Увлекаться, правда, не стоит. Дело в том, что исключение – класс все-таки выделенный. При создании Throwable существуют большие накладные расходы – заполнение стека вызова. Это достаточно длительная процедура. И потому создавать исключение просто так – себе дороже. Его нужно создавать только тогда, когда без него не обойтись, когда оно точно будет выброшено. Проще это делать сразу вместе с директивой throw .
А вот держать в классе исключения какую-то информацию, которая позволит его обработать – вполне допустимо. Передавать эту информацию лучше через конструктор.
Итак, приступим к более подробному рассмотрению. Первый базовый тип –
java.lang.Exception
Исключения этого типа я бы охарактерировал так – они возникают в ситуациях, которые нам неподконтрольны. Скажем, десериализуем мы класс, а данные в неверном формате. И мы с этим ничего не можем сделать, кроме как адекватно отреагировать.
Метод может декларировать любое количестко исключений. Нет, любое – это, наверное, слишком сильно сказано. Если мне не изменяет память, количество исключений ограничено 64K – 65536 штук. Для меня это уже означает, что я могу декларировать столько исключений, сколько мне заблагорассудится.
Перейдем теперь к последнему типу –
java.lang.Error
Как я уже упоминал, это критические ошибки, после которых восстановить нормальную работу практически нереально. В самом деле – ну что сделаешь при переполнении стека? Или если не найден метод? Или если вызван абстрактный метод? Или в случае ошибки в байт-коде класса? Абсолютно ничего. По крайней мере, без серьезного вмешательства человека, который может заменить библиотеку, например. Или поменять classpath .
В некоторых случаях ситуация не столь критична. Скажем, нехватка памяти, вызывающая java.lang.OutOfMemoryError . Если эта ошибка произошла в момент выделения большого объема памяти – например, при создании массива, – ее можно перехватить и попытаться выделить память в меньших объемах, изменив каким-то образом алгоритм, который будет эту память использовать.
Или, скажем, в случае, когда не JVM поддерживает системную кодировку – при попытке создать InputStreamReader без указания кодировки будет выброшена ошибка. Однако нужна ли нам системная кодировка и насколько для нас критично ее отсутствие – решать нам.
С классификацией закончили, переходим к следующему вопросу.
Инициация исключений
А вопрос следующий – что и когда бросать.
Представим себе, что у вас создалась исключительная ситуация и работать код дальше не может. Какой именно тип исключения использовать?
При написании бизнес-логики – в особенности это касается библиотек – часто бывает полезным создать собственный тип исключения. Просто для того, чтобы дать возможность обрабатывать ваши исключения отдельно от остальных. Подробнее об обработке – в следующем разделе.
Пара слов насчет приведенного примера – null в качестве параметра. Теоретически в этой ситуации можно бросить два исключения – NullPointerException и IllegalArgumentException . Нескотря на кажущуюся очевидность выбора я лично предпочитаю второй вариант. На мой взгляд NullPointerException должна бросать исключительно виртуальная машина. Если же я сам проверил значение и убедился, что оно равно null , а этого быть не должно – гораздо более информативно использовать IllegalArgumentException , если это значение аргумента, или же IllegalStateException – если это значение члена класса.
Ну ладно, что бросить именно – это мы как-нибудь определим. Но иногда возникает какое-то иррациональное желание не только бросить исключение, но и как-то его конкретизировать, указав причину. Не, можно, конечно, и по исключению на каждую ошибку создать, но сойти с ума намного проще и быстрее.
В этом случае может выручить механизм т.н. exception chaining – связывания исключений. Практически у каждого класса исключения есть конструктор, принимающий в качестве параметра Throwable – причину исключительной ситуации. Если же такого конструктора нет – у все того же Throwable , от которого унаследованы все исключения, есть метод initCause(Throwable) , который можно вызвать ровно один раз. И передать ему исключение, явившееся причиной того, что было инициировано следующее исключение.
Зачем это нужно. Дело в том, что хорошо спроектированный код – он как черный ящик. У него есть свои интерфейсы, определенное поведение, набор исключительных ситуаций, наконец. А что происходит внутри – это не играет роли для того, что находится снаружи. Более того – иногда может сыграть и обратный эффект. Причин для ошибки может быть добрый десяток, и ловить их все отдельно и так же обрабатывать. Чаще всего просто не нужно. Именно потому проще определить, например, свое исключение (ну или использовать имеющееся, не суть важно) и бросить именно его, указав как причину то, которое мы поймали. И волки сыты, и пользователям кода работы меньше.
Ну вот, от инициации исключений мы плавно переходим к их обработке.
Обработка исключений
Казалось бы, чего проще? Написал catch(Throwable th) – и всё. Однако именно от этого я их хочу предостеречь.
Во-первых, как я уже говорил выше, ловить исключения времени выполнения – дурной тон. Они свидетельствуют об ошибках. Ловить java.lang.Error или производные стоит только если вы точно знаете, что делаете. Восстановление после таких ошибок не всегда возможно и почти всегда нетривиально.
Во-вторых – как именно обрабатывать? Я об этом подробно писал в статье о качестве кода, раздел Обработка исключений, но повторюсь. По каждому пойманому исключению необходимо принимать решение. Просто проглотить его или вывести в консоль – самое неприятное, что можно придумать. А этим грешат, к сожалению, многие. Человек читает XML из файла, получает исключение, глотает его – и пытается дальше работать с этим XML так, как будто ничего не произошло. Естественно получает NullPointerException , поскольку класс, который он использует, не инициализировался. Ошибка разработчика, хотя и не столь очевидная.
Почему я говорил о том, что стоит заводить свои типы исключений – так вы проще сможете их выделить на стадии обработки. Представьте себе, что существуют пять причин, по которым может быть выброшено исключение, и во всех пяти случаях бросается java.lang.Exception . Вы же спятите разбираться, чем именно это исключение вызвано. А если это будет пять разных типов – тут уже проще простого. На каждый – свой блок catch .
И третье – что делать с иерархиями исключений. Пусть у вас метод может выбросить как IOException , так и Exception . Так вот, совершенно не все равно, в каком порядке будут стоять блоки catch , поскольку они обрабатываются ровно в той последовательности, как объявлены. И если первым будет catch(Exception ex) – до второго ( catch(IOException ioex) ) управление просто не дойдет. Компилятор об этом, конечно, предупредит, более того – это считается ошибкой. Тем не менее об этом стоит помнить.
Следующее, чего бы я хотел коснуться –
Перехват исключений, вызвавших завершение потока
При использовании нескольких потоков бывают ситуации, когда надо знать, как поток завершился. В смысле – если это произошло из-за исключения, то из-за какого именно. Для этой цели начиная с версии Java 5 существует специальный интерфейс – Thread.UncaughtExceptionHandler . Его реализацию можно установить нужному потоку с помощью метода setUncaughtExceptionHandler . Можно также установить обработчик по умолчанию с помощью статического метода Thread.setDefaultUncaughtExceptionHandler .
Интерфейс Thread.UncaughtExceptionHandler имеет один единственный метод – uncaughtException(Thread t, Throwable e) – в который передается экземпляр потока, завершившегося исключением, и экземпляр самого исключения. Восстановить работу потока, естественно, уже не удастся, но зафиксировать факт его ненормального завершения таким образом можно.
Следующее, о чем я хотел бы поговорить – сама конструкция try / catch / finally .
Конструкция try / catch / finally – тонкости
С блоком try , думаю, вопросов не возникает. С блоком catch – надеюсь, уже тоже нет. Остается блок finally . Что это, и с чем его едят?
Блок finally идет в самом конце конструкции try / catch / finally . Ключевая его особенность в том, что он выполняется всегда, вне зависимости от того, сработал catch или нет.
Зачем это нужно. Посмотрите вот на этот фрагмент кода:
Казалось бы все в порядке. А что будет, если, например, при вызове rs.first() произойдет исключение? Да, оно обработается. Однако ни ResultSet , ни Statement , ни Connection закрыты не будут. Последствия весьма печальны – исчерпание открытых курсоров, соединений в пуле и т.п.
Можно, конечно, поместить этот же код и в блок catch . Однако дублировать код – не лучшая идея. Правильнее вынести код закрытия в блок finally , в этом случае он будет исполнен как в случае возникновения исключения, так и в случае, когда этого не происходит.
Рассмотрим еще один пример:
Вопрос на засыпку – каков будет результат? Выполняем тест и получаем:
Т.е. в обоих случаях результат будет одинаковый, причем не тот, которого можно было бы ожидать! Почему так происходит? В первом случае – из блока try должно вернуться значение 6 – длина переданной строки. Однако выполняется блок finally , в котором возвращается 0. В результате исходное значение теряется. Во втором случае – попытка вызвать toString() при переданном значении null приведет к исключению – NullPointerException . Это исключение будет перехвачено, т.к. является наследником Exception . Из блока catch должно вернуться значение -1, однако выполняется блок finally и возвращается опять-таки 0, а -1 – теряется!
Точно так же блок finally может вызвать потерю исключений. Посмотрите вот на этот пример:
Этот тест очень часто давался на интервью. И правильно отвечали единицы. Между тем – результатом его выполнения будет вывод в консоль b. И только. После инициации первого исключения – new Exception("a") – будет выполнен блок finally , в котором будет брошено исключение new IOException("b") . И именно это исключение будет поймано и обработано. Исходное же исключение теряется.
Хотелось бы затронуть еще один момент. В каких комбинациях могут существовать блоки try , catch и finally ? Понятно, что try – обязателен. Он может быть совместно с catch , либо с catch и finally одновременно. Отдельно try не используется. А есть ли еще варианты?
Есть. try может быть в паре с finally , без catch . Работает это точно так же – после выхода из блока try выполняется блок finally . Это может быть полезно, например, в следующей ситуации. При выходе из метода вам надо произвести какое-либо действие. А return в этом методе стоит в нескольких местах. Писать одинаковый код перед каждым return нецелесообразно. Гораздо проще и эффективнее поместить основной код в try , а код, выполняемый при выходе – в finally .
И последняя тема –
Отсутствие транзакционности
В самом начале я упоминал о том, что организовать утечку памяти при использовании исключений в конструкторах сложно. На самом деле – можно. Смотрим на пример.
Итак, что тут происходит. В конструкторе мы присваиваем ссылку на созданный объект статической переменной. Дальше мы инициализируем одно поле и. бросаем исключение. Я это делаю намеренно, однако это может произойти и в результате выполнения кода конструктора. В методе main это исключение обрабатывается. Однако ссылка на объект – существует! В чем можно убедиться, выполнив приведенный код:
Переменная метода main равна null , как и положено. А вот статическая переменная self – нет. Через нее можно получить доступ к объекту, инициализация которого была прервана исключением. И объект этот, естественно, в неверном состоянии. Вот она – утечка памяти. Объект не будет удален до тех пор, пока на него есть ссылка.
Пример этот искуственный, но лишь до известной степени. Он говорит об очень важной особенности исключений:
Cвойством транзакционности исключения не обладают – действия, произведенные в блоке try до возникновения исключения, не отменяются поcле его возникновения.
И это необходимо учитывать. Применительно к приведенному примеру – стоит все операции, могущие привести к исключению, выполнять как можно раньше. Например, проверять переданные параметры сразу же. В некоторых случаях для отмены уже произведенных действий может пригодиться блок finally . А если очень надо где-то сохранить ссылку на создаваемый объект, причем сделать это необходимо в конструкторе – лучше всего оставить это напоследок, когда весь критический код уже выполнен.
Ну, вот и все. Думаю, большая часть этого материала вам была знакома. Во всяком случае, надеюсь на это. Моей целью было просто упорядочить информацию для тех, кто с исключениями пока еще знаком поверхностно. Всем спасибо!
Краткое описание:
Помогает решить проблемы оператора Билайн с большим количеством китайских и не китайских телефонов
Описание:
Как выглядит проблема:
1) Вы совершаете исходящий звонок другому абоненту.
2) Абонент берет трубку и идет разговор
3) Вы или абонент заканчиваете разговор
4) Открываете журнал звонков и видите там "Неизвестный" исходящий номер вместо номера вызванного абонента.
Какие телефоны и операторы подвержены проблеме:
Билайн
Почти все китайские телефоны на процессорах MTK.
Я читал упоминания в ветках Oukitel 4000, ZTE Blade 1, ZTE Blade Z7, Bluibo Picasso,Ulefone Paris,Cubot X16,Infocus M560 и тп. Были проблеы на Samsung Galaxy S3 и CM 13. Вообщем список огромный
Даже телефон 4GOOD S450m ,который продается в билайне по акции тоже подтвержен этой проблеме.
Билайн официальной отказывает признавать проблему и заявляет, что это не у них проблемы. Они частично правы, тк нормальные телефоны на стоковой прошивке лишены этих проблем.
Суть проблемы:
Проблема заключается в несовместимости некоторых операторов и некоторых прошивок телефонов.
Почти всегда проблема возникает на операторе Билайн, хотя я слышал про проблемы и с другими операторами.
Про Билайн известно следующее. После того, как другой абонент берет трубку - сеть передает на ваш телефон номер, на который переадресуется звонок. Почти всегда это набранный номер = переадресуемый номер. Но, если вы звоните с билайна на Теле2, то Теле2 возвращает билайну пустой переадресуемый номер, Билайн пустой переадресуемый номер возвращает вам на телефон и после разговора вы видите ,что в журнале вызовов у вас исходящий "Неизвестный" номер.
Это приложение как раз помогает решить проблему неизвестных исходящих в журнале вызовов.
Я не профессиональный разработчик, но пришлось гуглить и писать самому приложение, тк рабочих аналогов не нашел. Мне даже пришлось полгода назад в том числе изза этой проблемы продать 1 телефон.
Как работает приложение:
1) В начале исходящего вызова чистится весь лог звонков от неизвесных номеров и сохраняется внутри приложения набранный номер
2) После завершения исходящего вызова снова чистится лог звонков от неизвесных номеров и если хотябы 1 номер был удален, то в конец лога звонков записывается сохраненный в п. 1 номер.
Если вам помогло приложение, пожалуйста, отпишите какой у вас телефон и прошивка. Эта информация поможет другим страдальцам.
Важное дополнение для пользователей CM 13. На некоторых аппаратах на CM 13 прога не работает. Если у вас такая ситуация, попробуйте сделать следущие. Зайдити в настройки сим карты и ВКЛЮЧИТЕ опцию "Идентификация абонента". Мне в личку писали, что только после этой процедуры прога работала на СМ13.
Хотя вот лично на моем телефоне LG L90 ,все работает и с включенной и с выключенной опцией "Идентификация абонента".
Как проверить приложние? Если у вас Билайн, то позвоните кому-нибудь на Теле2, поговорите немного и положите трубку. В журнале звонков последний набранный номер должен отображаться правильно.
Если вам программа помогла - пожалуйста, пожертвуйте, по возможности, мне некоторую сумму. Реквизиты в профиле.
Всем уже пожертвовавшим - большое Спасибо.
Разработчик: Анатолий Румянцев
версия: 1.0.14 - только для прошивок MIUI
Unknown-Number-fix-1.0.14-debug.apk ( 1016.12 КБ )
Эта версия не имеет пользовательского интерфейса. На прошивках миуи программа постоянно выгружается из памяти и перестает работать. Обойти это можно, используя версию для миуи, и программы автоматизаторы tasker, llama automateit. Создайте правило, которое будет запускать ярлык программы 'Фикс неизвестного номера " после включения экрана или при запуске звонилки.
Читайте также: