поиск в реальном времени с использованием AsyncTask? - PullRequest
3 голосов
/ 01 декабря 2010

Я пишу приложение, которое ищет базу данных в режиме реального времени. то есть, когда пользователь нажимает буквы, он обновляет список результатов поиска.

Поскольку поиск может занять некоторое время, мне нужно выполнить поиск в фоновом режиме и разрешить нажатие новых клавиш для повторного запуска поиска. Таким образом, пользователь нажимает «a» (и код начинает поиск «a»), затем нажимает «b» - код НЕ будет ждать окончания поиска «a», затем начнет поиск «ab», а скорее Остановите поиск "a" и начните новый поиск "ab".

  • Для этого я решил выполнить поиск в AsyncTask. Это мудрое решение?

Теперь - всякий раз, когда обнаруживается нажатие клавиши, я проверяю, запущен ли AsyncTask. Если я это сделаю - я сигнализирую об этом (используя логическое значение в AsyncTask), он должен остановиться. Затем установите таймер для повторной проверки AsyncTask в течение 10 мсек, чтобы увидеть, завершился ли он, и начать новый поиск.

  • Это умный метод? Или есть другой подход, который вы бы выбрали?

ТИА

1 Ответ

3 голосов
/ 01 декабря 2010

Во-первых, AsyncTask - хороший способ сделать это. Проблема, которую я вижу с вашим подходом, заключается в том, что таймер ждет, когда кто-то умрет. Когда вы вызываете asyncTask, удерживайте ссылку на него. Пусть он сохранит состояние для вас, чтобы вы знали, находится ли он в поиске или он вернулся. Когда пользователь нажимает другое письмо, вы можете сказать, что asyncTask отменить. Примерно так:

public void onClick() {
   if( searchTask != null ) {
      searchTask.cancel();
   }

   searchTask = new SearchTask( MyActivity.this ).execute( textInput.getText() );
}

public class SearchTask extends AsyncTask<String,Integer,List<SearchResult>> {
    private boolean canceled = false;

    protected onPostExecute( List<SearchResult> results ) {
       if( !canceled ) {
          activity.handleResults( results );
       }
    }

    public void cancel() {
       canceled = true;
    }
}

Это безопасно, потому что onPostExecute () находится в потоке пользовательского интерфейса. И метод cancel () вызывается только из потока пользовательского интерфейса, поэтому проблем с безопасностью потока и синхронизации не требуется. Вам не нужно смотреть, как нить умирает. Просто позвольте ГХ справиться с уборкой. Как только вы уроните ссылку на AsyncTask, она будет просто очищена. Если ваш AsyncTask блокируется, это нормально, потому что он вешает только фоновый поток, а когда истекает время ожидания, он возобновляет работу, вызывая onPostExecute (). Это также сводит ваши ресурсы к минимуму без использования таймера.

Что следует учитывать при таком подходе. Отправка нового запроса каждый раз, когда набирается новая буква, может привести к перегрузке серверов, поскольку первые несколько букв будут давать самые большие результаты поиска. Либо ограничьте количество результатов, которые вы будете возвращать с сервера (скажем, максимум 10-50 результатов), либо подождите, пока они не введут достаточно символов, чтобы сохранить результаты (скажем, 3). Недостатком того, что пользователь вводит больше символов, является то, что обратная связь не срабатывает до 3 символов. Тем не менее, это значительно снизит количество посещений вашего сервера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...