Как организовать длительные (трудоемкие) действия на Android? - PullRequest
2 голосов
/ 11 февраля 2010

Например, мы находимся в SomeActivity, и у действия есть кнопка, которая вызывает перемещение файлов из одного каталога в другой (назовем это заданием).

На BlackBerry я бы:

  1. выдвинуть неотменяемое всплывающее окно (диалоговое окно) со словами «Пожалуйста, подождите ...»
  2. запустить поток, который выполняет задание
  3. при завершении потока, закрыть всплывающее окно

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

На Android все меняется.Я знаю, что есть AsyncTask, который, вероятно, предназначен для решения моего дела.Есть даже хороший пример того, как его следует использовать.Но поскольку нет гарантии того, как долго будет действовать экземпляр Activity, AsyncTask следует отменить в onSaveInstanceState (и перезапустить в onRestoreInstanceState).Это означает, что при использовании AsyncTask нет никакой гарантии, что мы сможем полностью выполнить работу после ее запуска.В некоторых случаях при отправке http-запроса на создание пользователя я не хотел бы сообщать о проблеме «пользователь уже существует для этого входа в систему» ​​при повторном запуске AsyncTask.Это возможно, поскольку AsyncTask может быть прервана, пока запрос уже отправлен (и сервер фактически выполняет свою работу - создает нового пользователя), но AsyncTask отменяется, прежде чем мы получим ответ.

Есть ликакое-нибудь решение на Android, чтобы получить BB-подобное поведение, указанное выше?

Ответы [ 3 ]

2 голосов
/ 11 февраля 2010

Но так как нет гарантии того, как долго будет жить экземпляр Activity AsyncTask должен быть отменен на onSaveInstanceState (и перезапущен на onRestoreInstanceState).

Или оно должно управляться Service.

1 голос
/ 11 февраля 2010

Если ваша активность хочет остаться на экране, вы можете просто запустить тему, например:

final File fromFile = ...;
final File toFile = ...;

new Thread() {
    @Override
    public void run() {
      // do something with fromFile, toFile
    }
}.start();

Таким образом, GUI-поток готов делать другие мысли, например, отображать

  android.app.ProgressDialog

Кроме того, рассмотрите возможность отмены диалога с помощью

  ProgressDialog.setCancelable(false);

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

  Activity.onPause()

называется. Кроме того, вы можете захотеть заглянуть в Wakelocks, чтобы экран не стал черным, а ваше приложение оказалось в фоновом режиме, где оно может быть убито. Вы бы сделали это в теме:

  PowerManager pm = (PowerManager) ivContext.getSystemService(Context.POWER_SERVICE);
  Wakelock wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "MyApp");
  wakeLock.acquire();

  // ... copy stuff ...

  wakeLock.release();

Конечно, вам также придется разблокировать wakeLock, когда пользователь уходит с помощью HOME-Key.

Наконец, если вы хотите вызывать GUI-Elements из вашего background-thread, это будет работать только в том случае, если Thread является частью GUI-Event-Loop, как обычный поток, в котором вы работаете, когда вас вызывают с помощью on ...- методы. Чтобы добиться этого, ваш фоновый поток должен будет перезвонить в GUI-поток через обработчик. Как это:

  private Handler mHandler = new Handler() { 
      @Override
      public void handleMessage(Message msg) {
          Log.v(TAG, "Got Message "+msg.what); // prints: Got Message 77
      // ... do GUI actions ...
      }    
  };

  // ... in Thread ...

  int lvInfo = 77;
  mHandler.sendEmptyMessage(lvInfo);

Вы даже можете помещать объекты в сообщение так:

  Message txtMsg = Message.obtain();
  textMsg.obj = "Hello World";
  mHandler.sendMessage(lvTextMsg);
0 голосов
/ 15 апреля 2011

В мае 2010 года Google выпустил новый сеанс ввода-вывода под названием Разработка клиентских приложений Android REST , в котором объясняется, как добиться именно того, о чем я просил.

Оказалось, вопрос довольно сложный, поэтому нет простого и быстрого решения. Решение требует глубоких знаний о платформе Android / API. Это цена, обусловленная гибкостью процесса приложения / жизненных циклов активности.

Мне странно, почему эта информация не была представлена ​​в самой первой версии Android. Похоже, Google знал, как написать 100% безошибочные приложения, и по какой-то маркетинговой причине не разделял этот подход. Только представьте, сколько глючных приложений было написано к маю 2010 года.

В любом случае, я рад, что у меня есть что-то, что мы называем наилучшей практикой.

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