Как справиться с AsyncTask во время поворота экрана? - PullRequest
86 голосов
/ 12 апреля 2010

Я много читал о том, как сохранить состояние моего экземпляра или как справиться с тем, что моя активность разрушается при повороте экрана.

Кажется, есть много возможностей, но я не выяснил, какая из них лучше всего подходит для получения результатов AsyncTask.

У меня есть несколько AsyncTasks, которые просто запускаются снова и вызывают метод isFinishing() действия, и если действие заканчивается, они ничего не обновят.

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

Как бы вы решили это? Каковы преимущества или недостатки возможных решений?

Ответы [ 13 ]

0 голосов
/ 19 ноября 2017

Вы также можете добавить андроид: configChanges = "keyboardHidden | ориентация | Размер экрана"

к вашему явному примеру, надеюсь, это поможет

 <application
    android:name=".AppController"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:theme="@style/AppTheme">
0 голосов
/ 09 ноября 2016
@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    final AddTask task = mAddTask;
    if (task != null && task.getStatus() != UserTask.Status.FINISHED) {
        final String bookId = task.getBookId();
        task.cancel(true);

        if (bookId != null) {
            outState.putBoolean(STATE_ADD_IN_PROGRESS, true);
            outState.putString(STATE_ADD_BOOK, bookId);
        }

        mAddTask = null;
    }
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
    if (savedInstanceState.getBoolean(STATE_ADD_IN_PROGRESS)) {
        final String id = savedInstanceState.getString(STATE_ADD_BOOK);
        if (!BooksManager.bookExists(getContentResolver(), id)) {
            mAddTask = (AddTask) new AddTask().execute(id);
        }
    }
}
0 голосов
/ 03 апреля 2015

Мое решение.

В моем случае у меня есть цепочка AsyncTasks с тем же контекстом. Активность имела доступ только к первому. Чтобы отменить любое запущенное задание, я сделал следующее:

public final class TaskLoader {

private static AsyncTask task;

     private TaskLoader() {
         throw new UnsupportedOperationException();
     }

     public static void setTask(AsyncTask task) {
         TaskLoader.task = task;
     }

    public static void cancel() {
         TaskLoader.task.cancel(true);
     }
}

Задание doInBackground():

protected Void doInBackground(Params... params) {
    TaskLoader.setTask(this);
    ....
}

Активность onStop() или onPause():

protected void onStop() {
    super.onStop();
    TaskLoader.cancel();
}
...