Выполните несколько задач синхронно в Android - PullRequest
0 голосов
/ 24 сентября 2010

Не знаю, как изящно решить следующую задачу:

  1. У меня есть несколько блоков кода (операции) для выполнения.
  2. Каждый блок может возвращать true из false, чтобы указать, что возможно дальнейшее выполнение.
  3. Внутри каждого блока я должен использовать асинхронные вызовы методов (потому что Android полностью асинхронный).

Пример операций обработки (теперь не работает должным образом):

      List<Operation> operations = command.getOperations();
      for (Operation operation : operations) {
          Log.d(TAG, "Processing operation: " + operation);
          OperationResult result = operation.execute(activity);
          Log.d(TAG, "Operation result is: " + result);
          if (!result.canContinue()) {
              break;
          }
      }

Проблема в том, что внутри операции мне нужно, например, отобразить AlertDialog и дождаться ввода. Но после того, как я вызываю dialog.show(), мой метод execute завершается и возвращает неверный результат.

Пример кнопки прослушивания, зарегистрированной в AlertDialog, приведен ниже:

 final OperationResult result = new OperationResult();
 final class ButtonListener implements DialogInterface.OnClickListener {

    public void onClick(DialogInterface dialog, int id) {
        switch (id) {
        case DialogInterface.BUTTON_POSITIVE: {
                result.setCanContinue(true);
        }
        case DialogInterface.BUTTON_NEGATIVE: {
            dialog.cancel();
                result.setCanContinue(false);
        }
    }
}

Как изменить обработку операций для поддержки асинхронной модели Android?

Ответы [ 2 ]

3 голосов
/ 24 сентября 2010

Если объем выполняемой обработки находится в диапазоне миллисекунд, вы можете реструктурировать свой код как конечный автомат - список перечисляемых подзадач и переменную, которая отслеживает текущую или следующую задачу, которая должна быть выполнена.По сути, когда приходит событие, вы будете работать со списком дел, пока не доберетесь до задачи (состояния), которая требует результата асинхронной операции.В этот момент вы запускаете асинхронную операцию и возвращаетесь.Когда вы получаете вызов события из пользовательского ввода или чего-либо еще, вы записываете данные, а затем возобновляете выполнение конечного автомата с сохраненного номера состояния, пока он снова не выполнит асинхронную операцию, и вы вернетесь.Но это работает только в том случае, если время, которое вы тратите на обработку, измеряется в миллисекундах, в противном случае вы действуете медленно и не отвечаете, вызывая ANR в крайних случаях.

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

0 голосов
/ 25 сентября 2010

Хорошо, вот как я решил проблему:

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