- Для чего предназначено IllegalStateException?
- Illegal State Exception Class
- Definition
- Remarks
- Constructors
- Fields
- Properties
- Methods
- Explicit Interface Implementations
- Extension Methods
- Ошибка Android: java.ленг.IllegalStateException: попытка запросить уже закрытый курсор
- 6 ответов
- Android 8.0: Java.lang.IllegalStateException: запрещено запускать службу
- В Oreo Android определено ограничения для фоновых сервисов .
- вы не хотите получать уведомления для своего сервиса?
Для чего предназначено IllegalStateException?
Это появилось в дискуссии с коллегой сегодня.
Javadocs для Java IllegalStateException утверждают, что он:
Сигналы о том, что метод был вызван в незаконное или ненадлежащее время. Другими словами, среда Java или приложение Java не находятся в соответствующем состоянии для запрошенной операции.
И эффективная Java говорит (Пункт 60, страница 248):
Другим обычно используемым исключением является IllegalStateException. Это, как правило, исключение для броска, если вызов является незаконным из-за состояния принимающего объекта. Например, это было бы исключение для броска, если вызывающий пытался использовать какой-либо объект, прежде чем он был правильно инициализирован.
Кажется, здесь немного расхождения. Во втором предложении javadocs звучит так, что исключение может описывать очень широкое условие состояния выполнения Java, но описание в Effective Java делает его похожим на условия, связанные конкретно с состоянием состояния объекта, метод был вызван.
Устройства, которые я видел в JDK (например, коллекции, Matcher ) и в Guava, определенно, похоже, относятся к категории, о которой говорит Effective Java ( «Этот объект находится в состоянии, когда этот метод не может быть называется» ). Это также похоже на IllegalStateException sibling IllegalArgumentException .
Существуют ли в JDK законные IllegalStateException -услуги, которые относятся к «среде Java» или «Java-приложению»? Или какие-либо рекомендации по лучшей практике пропагандируют его использование для более широкого состояния исполнения? Если нет, то почему это так называемые javadocs?;)
Источник
Illegal State Exception Class
Definition
Some information relates to prerelease product that may be substantially modified before it’s released. Microsoft makes no warranties, express or implied, with respect to the information provided here.
Signals that a method has been invoked at an illegal or inappropriate time.
Remarks
Portions of this page are modifications based on work created and shared by the Android Open Source Project and used according to terms described in the Creative Commons 2.5 Attribution License.
Constructors
Constructs an IllegalStateException with no detail message.
A constructor used when creating managed representations of JNI objects; called by the runtime.
Constructs an IllegalStateException with no detail message.
Constructs an IllegalStateException with no detail message.
Constructs an IllegalStateException with no detail message.
Fields
Properties
Returns the cause of this throwable or null if the cause is nonexistent or unknown.
(Inherited from Throwable)
The handle to the underlying Android instance.
(Inherited from Throwable)
Creates a localized description of this throwable.
(Inherited from Throwable)
Returns the detail message string of this throwable.
(Inherited from Throwable)
This API supports the Mono for Android infrastructure and is not intended to be used directly from your code.
This API supports the Mono for Android infrastructure and is not intended to be used directly from your code.
Methods
Appends the specified exception to the exceptions that were suppressed in order to deliver this exception.
(Inherited from Throwable)
Fills in the execution stack trace.
(Inherited from Throwable)
Provides programmatic access to the stack trace information printed by #printStackTrace() .
(Inherited from Throwable)
Returns an array containing all of the exceptions that were suppressed, typically by the try -with-resources statement, in order to deliver this exception.
(Inherited from Throwable)
Initializes the cause of this throwable to the specified value.
(Inherited from Throwable)
Prints this throwable and its backtrace to the standard error stream.
(Inherited from Throwable)
Prints this throwable and its backtrace to the standard error stream.
(Inherited from Throwable)
Prints this throwable and its backtrace to the standard error stream.
(Inherited from Throwable)
Sets the Handle property.
(Inherited from Throwable)
Sets the stack trace elements that will be returned by #getStackTrace() and printed by #printStackTrace() and related methods.
(Inherited from Throwable)
Explicit Interface Implementations
IJavaPeerable.Disposed() | (Inherited from Throwable) |
IJavaPeerable.DisposeUnlessReferenced() | (Inherited from Throwable) |
IJavaPeerable.Finalized() | (Inherited from Throwable) |
IJavaPeerable.JniManagedPeerState | (Inherited from Throwable) |
IJavaPeerable.SetJniIdentityHashCode(Int32) | (Inherited from Throwable) |
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) | (Inherited from Throwable) |
IJavaPeerable.SetPeerReference(JniObjectReference) | (Inherited from Throwable) |
Extension Methods
Performs an Android runtime-checked type conversion.
Источник
Ошибка Android: java.ленг.IllegalStateException: попытка запросить уже закрытый курсор
окружающая среда (Linux/Eclipse Dev для планшета Xoom под управлением HoneyComb 3.0.1)
в моем приложении я использую камеру (startIntentForResult ()), чтобы сделать снимок. После того, как снимок сделан, я получаю обратный вызов onActivityResult() и могу загрузить растровое изображение с помощью Uri, переданного через намерение «сфотографировать». В этот момент моя деятельность возобновляется, и я получаю ошибку, пытаясь перезагрузить изображения в галерею:
единственная логика курсора Я использую это после изображение берется я конвертирую Uri в файл, используя следующую логику
любые идеи, что я делаю неправильно?
6 ответов
похоже, что вызов managedQuery () устарел в API Honeycomb.
Doc для managedQuery () читает:
также я заметил, что вызываю курсор.close () после запроса, который, я думаю, является no-no. Нашел это очень полезная ссылка как хорошо. После некоторого чтения я придумал это изменение, которое, кажется, работает.
для записи, вот как я исправил это в своем коде (который работает на Android 1.6 и выше): проблема в моем случае заключалась в том, что я непреднамеренно закрывал управляемые курсоры, вызывая CursorAdapter.changeCursor(). Вызываю Активность.stopManagingCursor () на курсоре адаптера перед изменением курсора решил проблему:
исправить: используйте context.getContentResolver().query вместо activity.managedQuery .
я создал этот вопрос здесь, поскольку я не мог прокомментировать последний ответ (комментарии отключены по какой-то причине). Я думал, что открытие новой темы только усложнит ситуацию.
я получаю сбои приложений, когда я иду от Действие A to Действие B а затем вернуться к Действие A. Это не происходит все время — только иногда и мне трудно найти, где именно это происходит. Все происходит на то же устройство (Nexus S), но я не считаю, что это проблема устройства.
у меня есть несколько вопросов относительно ответа @Martin Stine.
- в документации говорится о changeCursor(c); : «измените базовый курсор на новый курсор. Если есть существующий курсор, он будет закрыт». Так почему же я должен stopManagingCursor(currentCursor); — это не перебор?
- когда я использую код, предлагаемый @Martin Stine, я получаю исключение нулевого указателя. Причина то есть, что в первом «запуске» приложения ((SimpleCursorAdapter)getListAdapter()) будет оцениваться как NULL, потому что курсор еще не был создан. Конечно, я мог бы проверить, не получаю ли я null и только затем попытаться остановить управление курсором, но, наконец, я решил поместить свой » stopManagingCursor(currentCursor); в метод onPause() этого действия. Я думал, что таким образом у меня наверняка будет курсор, чтобы перестать управлять, и я должен сделать это, прежде чем я оставлю действие другому. Проблема — я использую несколько курсоры (один для заполнения текста поля EditText, а другой для представления списка) в моей деятельности, я думаю, не все из них связаны с курсором ListAdapter —
- как узнать, какой из них перестать управлять? Если у меня есть 3 разных списка?
- должен ли я закрыть все из них во время onPause() ?
- как получить список всех моих открытых курсоров?
так много вопросов. Надеюсь, кто-нибудь сможет помощь.
когда я доберусь до onPause() у меня есть курсор, чтобы остановить управление, но я еще не определил, решает ли это проблему, поскольку эта ошибка появляется спорадически.
ПОСЛЕ НЕКОТОРОГО РАССЛЕДОВАНИЯ:
я нашел кое-что интересное, что может дать ответ на «таинственную» сторону этого вопроса:
Activity A использует два курсора: один для заполнения поля EditText. Другой — заполнить ListView.
при переходе от действия A к действию B и возвращении поле + ListView в действии A должно быть заполнено снова. Похоже, что поле EditText никогда не будет иметь проблем с этим. Я не мог найти способ получить текущий курсор поля EditText (например, в Cursor currentCursor = ((SimpleCursorAdapter)getListAdapter()).getCursor(); ) и причина говорит мне, что поле EditText не будет его хранить. С другой стороны, ListView «запомнит» свой курсор с прошлого раза (до действия A -> действие B). Кроме того, и это странная вещь, Cursor currentCursor = ((SimpleCursorAdapter)getListAdapter()).getCursor(); будет иметь другой идентификатор после действия B — > Activity A и все это без меня всегда зовут
Я думаю, что в некоторых случаях, когда системе нужно освободить ресурсы, курсор будет убит, а когда действие B -> действие A, система все равно попытается использовать этот старый мертвый курсор, что приведет к исключению. И в других случаях система придумает новый курсор, который все еще жив, и, таким образом, никаких исключений не произойдет. Это может объяснить, почему это появляется только иногда. Я думаю, это трудно отладить из-за разницы в скорости приложения при запуске или отладке приложения. При отладке требуется больше времени и, таким образом, может дать системе время придумать новый курсор или наоборот.
в моем понимании это делает использование
как рекомендовано @Martin Stine a должны в некоторых случаях и резервные in Другие: если я возвращаюсь к методу, и система пытается использовать мертвый курсор, необходимо создать новый курсор и заменить его в ListAdapter, иначе я получаю сердитых пользователей приложения с разбитым приложением. В другом случае, когда система найдет себе новый курсор — строки выше избыточны, поскольку они аннулируют хороший курсор и создают новый.
Я думаю, чтобы предотвратить эту избыточность, мне нужно что-то вроде этого:
Источник
Android 8.0: Java.lang.IllegalStateException: запрещено запускать службу
При запуске приложения приложение запускает службу, которая должна выполнить некоторую сетевую задачу . После нацеливания на уровень API 26 моему приложению не удается запустить службу на Android 8.0 в фоновом режиме.
Вызывается: Java.lang.IllegalStateException: не разрешено запускать Намерение службы < CMP = my.app.tt/com.my.service >: приложение находится в фоновом режиме uid UidRecord
насколько я понимаю, это связано с: Пределы выполнения фона
Метод startService () теперь генерирует исключение IllegalStateException, если Приложение, ориентированное на Android 8.0, пытается использовать этот метод в ситуации, когда не разрешено создавать фоновые сервисы.
«в ситуации, когда это не разрешено» — что это на самом деле значит ?? И как это исправить. Я не хочу устанавливать свой сервис как «передний план»
Разрешенные ситуации — это временный белый список, в котором фоновая служба работает так же, как и до Android O.
При определенных обстоятельствах фоновое приложение помещается во временный белый список на несколько минут. Пока приложение находится в белом списке, оно может запускать службы без ограничений, и его фоновые службы могут запускаться. Приложение помещается в белый список, когда оно обрабатывает задачу, которая видна пользователю, например:
- Обработка высокоприоритетного сообщения Firebase Cloud Messaging (FCM).
- Получение трансляции, такой как SMS/MMS-сообщение.
- Выполнение PendingIntent из уведомления.
- Запуск VpnService до того, как приложение VPN выходит на передний план.
Другими словами, если ваша фоновая служба не соответствует требованиям белого списка, вы должны использовать новый JobScheduler . По сути, это то же самое, что и фоновая служба, но она вызывается периодически, а не работает в фоновом режиме.
Если вы используете IntentService, вы можете перейти на JobIntentService. Смотрите @ kosev’s ответ ниже .
Я получил решение. Для устройств до 8.0 вы должны просто использовать startService() , но для устройств после 7.0 вы должны использовать startForgroundService() . Вот пример кода для запуска сервиса.
А в классе обслуживания, пожалуйста, добавьте код ниже для уведомления:
Где O — версия для Android 26.
Надеюсь, это решит IllegalArgumentException
Лучше всего использовать JobIntentService , который использует новый JobScheduler для Oreo или старые сервисы, если они недоступны.
Объявите в своем манифесте:
И в вашем сервисе вы должны заменить onHandleIntent на onHandleWork:
Затем вы начинаете свою службу с:
Если служба работает в фоновом потоке с расширением IntentService , вы можете заменить IntentService на JobIntentService , который предоставляется как часть библиотеки поддержки Android
Преимущество использования JobIntentService состоит в том, что он ведет себя как IntentService на устройствах pre-O и на O и выше, он отправляет его как задание
JobScheduler также может использоваться для периодических/по требованию заданий. Но убедитесь, что вы работаете с обратной совместимостью, так как API JobScheduler доступен только из API 21
Да, это потому, что вы больше не можете запускать службы в фоновом режиме через API 26. Таким образом, вы можете запустить ForegroundService выше API 26.
Вам придется использовать
и опубликовать уведомление при обработке утечки.
В заметках о выпуске firebase говорится, что поддержка Android O была впервые выпущена в 10.2.1 (хотя я бы порекомендовал использовать самую последнюю версию).
пожалуйста, добавьте новые зависимости Firebase для Android O
обновить службы Google Play и Google репозитории, если это необходимо.
Я вижу много ответов, которые рекомендуют просто использовать ForegroundService. Чтобы использовать ForegroundService, должно быть уведомление, связанное с ним. Пользователи увидят это уведомление. В зависимости от ситуации они могут раздражать ваше приложение и удалять его.
Самое простое решение — использовать новый компонент архитектуры под названием WorkManager. Вы можете проверить документацию здесь: https://developer.Android.com/topic/libraries/architecture/workmanager/
Вы просто определяете свой рабочий класс, который расширяет Worker.
Затем вы планируете, когда вы хотите запустить его.
Легко! Существует множество способов настройки рабочих. Он поддерживает повторяющиеся задания, и вы можете даже делать сложные вещи, такие как цепочка, если вам это нужно. Надеюсь это поможет.
Как сказал @kosev в его ответ вы можете использовать JobIntentService. Но я использую альтернативное решение — я ловлю IllegalStateException и запускаю службу в качестве переднего плана. Например, эта функция запускает мой сервис:
и когда я обрабатываю Intent, я делаю следующее:
если вы встроили push-уведомление для Firebase,
Добавьте новые/обновите зависимости сообщений Firebase для Android O (Android 8.0) из-за Пределы фонового выполнения .
обновить службы Google Play и Google репозитории, если это необходимо.
Обновление:
Если вы выполняете свой код на 8.0, то приложение будет аварийно завершать работу. Так что запускайте сервис на переднем плане. Если ниже 8.0 используйте это:
Если выше или 8.0, то используйте это:
Используйте startForegroundService() вместо startService() И не забудьте создать startForeground(1,new Notification()); в вашем сервисе в течение 5 секунд после запуска сервиса.
В Oreo Android определено ограничения для фоновых сервисов .
Чтобы улучшить пользовательский опыт, Android 8.0 (уровень API 26) налагает ограничения на то, что приложения могут делать во время работы в фоновом режиме.
Тем не менее, если вам нужен всегда запущенный сервис, вы можете использовать приоритетный сервис.
Фоновые ограничения службы: Пока приложение не используется, существуют ограничения к его использованию фоновых услуг. Это не относится к переднему плану услуги, которые более заметны для пользователя.
Таким образом, вы можете сделать передний план службы. Вам нужно будет показать уведомление пользователю, когда ваша служба работает. Смотрите этот ответ (Есть много других)
вы не хотите получать уведомления для своего сервиса?
Вы можете выполнять периодическое задание, 1. оно запускает ваш сервис, 2. сервис выполнит свою работу и 3. останавливается сам. При этом ваше приложение не будет считаться разрядкой аккумулятора.
- Work manager — лучшее решение для периодических задач. Который был представлен с Android Architecture Component .
- В отличие от Job-Scheduler (только> 21 API) он будет работать для всех версий.
- Также он начинает работать после режима Doze-Standby .
- Сделайте Android Boot Receiver для планирования сервиса после загрузки устройства.
Я протестировал постоянно работающий сервис с Work-Manager.
Если какое-либо намерение ранее работало нормально, когда приложение находится в фоновом режиме, это больше не будет иметь место в Android 8 и выше. Имеется в виду только намерение, которое должно выполнять некоторую обработку, когда приложение находится в фоновом режиме.
Следующие шаги должны быть выполнены:
- Вышеупомянутое намерение должно использовать JobIntentService вместо IntentService .
Класс, который расширяет JobIntentService , должен реализовывать метод — onHandleWork(@NonNull Intent intent) и должен иметь метод ниже , Который вызовет метод onHandleWork :
Вызовите enqueueWork(Context, intent) из класса, в котором определены ваши намерения.
Приведенный ниже класс ранее расширял класс Service
com.Android.support:support-compat необходим для JobIntentService — я использую 26.1.0 V .
Самое главное, чтобы версия библиотек Firebase была как минимум на 10.2.1 , у меня были проблемы с 10.2.0 — если таковые имеются!
Ваш манифест должен иметь приведенное ниже разрешение для класса Service:
Надеюсь это поможет.
Я думаю, что лучший способ обойти это — проверить версию сборки во время выполнения и, в зависимости от этого, если она меньше, чем Api level 21, продолжать использовать startService (). но если оно выше, вы должны использовать планировщик заданий. Я думаю, вы можете использовать менеджер работ, но он все еще находится в стадии бета-тестирования
Источник