2010-02-17 3 views
4

Вот сценарий:Android: как правильно ждать завершения процесса обслуживания

  1. У меня 2 мероприятия и одну услуги
  2. Первая деятельность представляет собой вид посадки/страница поиска. Во-вторых активность отображает результаты поиска
  3. Поиск всегда выполняется с внутренней БД SQLite
  4. Периодически (например ежедневно) дб необходимо обновить из удаленного источника, который является длительным процессом
  5. Если пользователь выполняет поиск в процессе обновления I хотите дождаться завершения обновления при отображении предупреждения «Подождите». Я не хочу запрашивать и отображать результаты поиска, пока обновление не будет полностью завершено.
  6. Обновление db запускается AlarmManager и выполняется службой, которая ставит статус «ОБНОВЛЕНИЕ» в db во время обновления.
  7. Я могу легко запросить статус, но как подождать и периодически повторно запрашивать базу данных? Я использую AsyncTask для обработки результатов поиска, и моя реакция коленного рефлекса заключалась в том, чтобы поместить цикл с wait() в метод AsyncTask#doInBackground, но это опасно и просто не работает, так как я не контролирую поток пользовательского интерфейса, поэтому в итоге IllegalMonitorStateException.

Что будет «правильным» способом надлежащего ожидания (может быть, даже с обновлением статуса) в этом случае?

P.S. Я поместил код ожидания в Runnable и выполнил его еще до того, как я доберусь до своей AsyncTask. Он работает, например. Thread.sleep(2000) все еще я не уверен, что это способ сделать это безопасно. Есть ли у кого-нибудь опыт работы с FutureTask?

ответ

2

Если пользователь выполняет поиск во время обновления я хочу ждать, пока обновление не закончится во время отображения «Пожалуйста, подождите» прогресс предупреждение. Я не хочу запрашивать и отображать результаты поиска, пока обновление не будет выполнено.

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

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

Или, чтобы обновление выполнялось таким образом, что оно является атомарным (например, делать обновление на копии таблицы, а затем синхронизировать таблицы в транзакции), чтобы активность могла безопасно в то время как обновление происходит.

Что бы «правильный» способ правильно ждать (может быть даже со статусом обновления) в этом случае?

Сообщайте об этом службе, когда обновление выполнено, посредством какого-либо обратного вызова или, возможно, трансляции. Держите индикатор прогресса до тех пор, пока это не произойдет. Это все еще вводит некоторые временные задачи, поэтому я просто откажусь от этого требования.

+0

Я думал по тем же линиям. Я не могу отложить обновление, так как пользователь может начать работу, пока обновление уже выполняется. Таким образом, я сделаю флип (это другой вопрос), который подает пользовательские данные до тех пор, пока обновление не будет выполнено. Однако есть две проблемы, которые остаются: 1. Как насчет первоначального обновления после того, как пользователь впервые установил приложение? В этот момент нет ничего, что можно было бы перевернуть, поскольку у меня нет старых данных. 2. Я предоставляю пользователю возможность принудительно обновить. В этот момент мне нужно показать пользователю, что обновление выполняется. – Bostone

+0

«Нет ничего, чтобы перевернуть в этот момент, так как у меня пока нет старых данных» :: shrug: см., Если таблица пуста, и пропустите флип или что-то еще , «В этот момент мне нужно показать пользователю, что обновление выполняется» - используйте технику в последнем абзаце моего ответа. Проблема синхронизации отпадает (я думаю), потому что пользователь инициирует обновление. – CommonsWare

+0

Пропустить флип очевидно ... На самом деле я просто придумал, что вместо того, чтобы заставить пользователя ждать, глядя на диалог прогресса, я могу постепенно добавлять в ListView (пока отображается индикатор обновления внизу). Служба может сообщать обновления обратно в представление – Bostone

0

Спасибо Mark (как всегда) за полезную информацию.Здесь я собираюсь изложить, как (на мой взгляд) выше сценарий должно быть сделано:

  1. Вместо того, чтобы тыкать базы данных просто привязать к услуге и начать ждет
  2. Если вы не можете связываться с сервис тогда он не работает, поэтому нет необходимости обезьяньям с ним - просто запросите db и сделайте то, что вам нужно
  3. Когда служба активирована, начните ждать и обрабатывать любые отзывы, которые отправляет служба. Это могут быть промежуточные обновления, а затем окончательный индикатор того, что услуга завершена.
+1

Вам действительно не нужно связываться с сервисом. Если это все ваше приложение, вы можете иметь статическую информацию, содержащую указатель на службу, которая установлена ​​в Service.onCreate() и очищена в Service.onDestroy(). Затем, когда ваша активность хочет взаимодействовать с этой службой, посмотрите на статику и используйте ее, если она не равна нулю. Оттуда это просто простая Java. – hackbod

+0

На самом деле - я закодирован с анонимным BroadcastReceiver, так как мне не нужно общаться с Activity to Service – Bostone