Задание асинхронного запускается и заканчивается в разных действиях - PullRequest
1 голос
/ 22 ноября 2011

Я бы хотел добиться следующего поведения, но я не уверен, как:

  1. Пользователь запускает действие
  2. Активность запускает AsyncTask
  3. Пользовательвыполняет какое-то действие, которое создает новое действие
  4. AsyncTask завершает работу и каким-то образом возвращает результат новому действию

Есть ли способ достичь этого поведения?

Спасибо

Ответы [ 4 ]

5 голосов
/ 22 ноября 2011

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

0 голосов
/ 22 ноября 2011

A Сервис - это компонент, который позволяет некоторому коду иметь отдельное время жизни вне действий без взаимодействия с пользователем. Как уже упоминали другие, это, безусловно, один вариант для рассмотрения. Если вы согласитесь с этим, IntentService - самый простой способ сделать работу асинхронной.

Тем не менее, вы можете продолжать использовать AsyncTask и просто добавить код, чтобы показать, что он «завершен». Это тот случай, когда фоновая работа больше не имеет значения, если ваше приложение убито, и вы в порядке, если ваше приложение будет убито до того, как эта работа будет завершена, если пользователь покинет приложение. Другой способ убедиться в этом, если результат AsyncTask имеет значение только для одного или обоих из этих двух действий, а не снаружи. Это важное отличие в требованиях от необходимости в услуге, которая, опять же, обеспечивает срок службы вне деятельности.

Чтобы передать данные, взгляните на этот документ . Есть много способов, которыми вы могли бы заняться этим, но для такого рода вещей я предпочитаю псевдо-синглтонный подход. (Я не люблю использовать SharedPreferences для передачи данных, потому что, честно говоря, я не думаю, что это то, для чего предназначен класс. Я предпочитаю этот псевдо-синглтонный подход, чем чистый синглтон, потому что он более тестируемый. Android использует синглтонный подход во всем место.) Я бы создал ссылку на какой-то класс регистратора AsyncTask в объекте Application. Поскольку объект Application доступен из обеих операций, первая может зарегистрировать AsyncTask у регистратора, а вторая может получить эту AsyncTask и зарегистрироваться для прослушивания на завершение, если она еще не завершена.

0 голосов
/ 22 ноября 2011

Это способ сделать именно то, что вы хотите, предполагая, что результатом является int.Вы можете расширить это свойство, используя объект parcelable.Возможно, использование Сервиса по-прежнему лучший выбор.

1) Создайте класс с именем Result, который является оберткой для вашего результата.Он должен реализовывать интерфейс Parcelable :

public class Result implements Parcelable {
    private int result;

    public Result(int i) {
        super();
        result = i;
    }

    public void setResult(int result) {
        this.result = result;
    }

    public int getResult() {
        return result;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(result);
    }

    public static final Parcelable.Creator<Result> CREATOR = new Parcelable.Creator<Result>() {
        public Result createFromParcel(Parcel in) {
            return new Result(in);
        }

        public Result[] newArray(int size) {
            return new Result[size];
        }
    };

    public Result(Parcel in) {
        result = in.readInt();
    }

}

2) Теперь вы можете использовать объект Result в качестве закрытой переменной первой операции:

public class FirstActivity extends Activity {
    private Result result;

    ....
}

3) В вашем первом действии вы можете запустить AsyncTask со следующей строкой:

new MyAsyncTask(result).execute();

4) AsyncTask может быть выполнен следующим образом:

class MyAsyncTask extends AsyncTask<Void, Void, Void> { // you can modify types as you want
    Result result;
    public MyAsyncTask(Result result) {
        this.result = result;
    }

    ....

    public mySetResult() {
        result.setResult(...); //set your value
    }

    ....
}

5)запустив второе задание, вы можете передать свой объект результата второму заданию:

Intent i = new Intent(getApplicationContext(), SecondActivity.class);
i.putExtra("parc", result);
startActivity(i);

6) Наконец, из второго задания вы можете получить результат, используя этот код:

Result res = (Result) getIntent().getParcelableExtra("parc");

Подробнее об объекте, подлежащем продаже, см. Android Developer

0 голосов
/ 22 ноября 2011

Я использовал вариант, предложенный Крисом:

Начните с создания IntentService , который является самым простым видом Service для создания.Затем используйте SharedPreferences , чтобы указать состояние вашего IntentService и поделиться значениями между вашими Service и Activities.Ваш Activity может зарегистрироваться как OnSharedPreferenceChangeListener , чтобы знать, когда ваш Сервис завершил работу и / или другой SharedPreference, о котором он заботится, изменился.вам нужно переопределить метод onHandleIntent.Все внутри onHandleIntent будет работать в фоновом потоке.

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