Bezdepbonusu7Программирование: статьи и ответы

Вопрос

IntentService застревает

Автор вопроса: AndrewОтветов: 1

Я создал приложение, которое использует IntentService для управления базой данных приложения и вызова веб-служб.

Пример:

У меня есть активность, которая представляет собой список элементов. Этот список заполняется CursorAdapter. У каждого элемента есть флажок, и список упорядочен по отмеченным (неотмеченные элементы вверху и отмеченные элементы внизу). Когда флажок элемента установлен, я отправляю Intent в свой IntentService, сообщая ему, чтобы отметить отмеченный столбец в таблице базы данных для этого элемента, затем передается сообщение, действие видит его и повторно запрашивает курсор.

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

Насколько я понимаю, намерения, переданные в IntentServices, не обрабатываются асинхронно. Это правильно? Он ведет себя почти так, как будто мне нужно использовать семафоры, но я не могу понять, почему, если намерения ставятся в очередь и обрабатываются индивидуально.

Допустим, я установил 3 флажка; поэтому в очереди 3 намерения. После первого я передаю сообщение, которое получает действие, сообщая ему, что нужно запросить его курсор. Может ли потенциальная проблема заключаться в том, что я повторно запрашиваю курсор одновременно с обработкой второго намерения (обновлением другой строки в таблице)? Запрос курсора происходит в потоке пользовательского интерфейса.

^ Я думаю, что это моя проблема. Что я должен использовать для синхронизации этого? Семафоры? Может ли кто-нибудь указать мне на некоторые документы/примеры?

Другая потенциальная проблема заключается в том, что если моя активность управляет курсором на столе; также мой IntentService запрашивает курсор из той же таблицы. У меня есть случаи, когда это происходит, когда мой IntentService просматривает каждую строку в курсоре, чтобы найти элементы для отправки в веб-службу. Хотя я не думаю, что это будет проблемой, пока курсоры не запрашивают одновременно?

У кого-нибудь есть другие идеи?

  • Несколько быстрых мыслей: я бы добавил ведение журнала в каждую часть системы, чтобы действительно найти, в чем проблема. Является ли уровень доступа к БД ContentProvider (они не предназначены для многопоточности)? Кроме того, зачем использовать IntentService, когда подойдет обработчик в действии? Аналогичным образом, зачем беспокоиться об асинхронной публикации обновлений, если действие все равно запрашивает БД в основном потоке, а не (скажем) в AsyncQueryHandler? Christopher Orr 06.10.2010
  • Да, мой доступ к БД осуществляется через ContentProvider. Я посмотрю на AsyncQueryHandler Andrew 07.10.2010

androidandroid-intentservice

Ответы

Ответ 1 · рейтинг 1 · CommonsWare

Когда флажок элемента установлен, я отправляю Intent в свой IntentService, сообщая ему, чтобы отметить отмеченный столбец в таблице базы данных для этого элемента, затем передается сообщение, действие видит его и повторно запрашивает курсор.

Это похоже на "бьюик, чтобы прихлопнуть муху".

Насколько я понимаю, намерения, переданные в IntentServices, не обрабатываются асинхронно. Это правильно?

onHandleIntent() в вашем IntentService вызывается в фоновом потоке, а startService() всегда асинхронно.

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

Отдельные Intents ставятся в очередь и последовательно обрабатываются IntentService.

Может ли потенциальная проблема заключаться в том, что я повторно запрашиваю курсор одновременно с обработкой второго намерения (обновлением другой строки в таблице)?

Это, конечно, не помогает.

Что я должен использовать для синхронизации этого? Семафоры?

Я бы просто использовал synchronized(someStaticDataMember), но семафоры должны работать.

Хотя я не думаю, что это будет проблемой, пока курсоры не запрашивают одновременно?

Фактический запрос не выполняется до тех пор, пока не коснется Cursor (например, moveToFirst(), getCount()). После этого, пока набор результатов запроса меньше 1 МБ, результаты полностью находятся в папке Cursor.

Я частично согласен с Кристофером: используйте ведение журнала, чтобы точно выяснить, что происходит, и подумайте о том, чтобы сделать это немного более легким (например, AsyncTask для записи в базу данных, а не IntentService).

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы