Вопрос по multithreading, android, android-asynctask, java – После ASyncTask.execute () выполните x () из Activity

4

Это тот, который я не знаю, как поступить. По сути, у меня есть класс ASyncTask, который работает как обычно в фоновом режиме. Я хотел бы сделать что-нибудь после того, как он закончится. Теперь, прежде чем прыгнуть вперед и сказать «просто используйте onPostExecute ()», есть загвоздка. Метод, который мне нужно запустить, находится в действии, а не в классе Task.

На мой взгляд, у меня есть 2 варианта.

A:
<code>    CustomTask task = new CustomTask();
    task.execute(passedParams);
            //when(task.execute is finished)
            {
                doX();
            }
</code>

Я надеюсь, что смогу сделать это таким образом, поскольку это так просто и позволяет мне проверять, когда задача завершена, без необходимости постоянно опрашивать ее на предмет активности и getStatus () на ней. Я не думаю, что мне повезет, но если у кого-то есть способ сделать это, это было бы здорово

B:

Передайте действие как параметр в ASyncTask. Это грязно, и я не рад его использованию, но помимо этого и ссылки на объект, я не знаю, будет ли это работать

<code>    CustomTask task = new CustomTask();
    task.execute(passedParams,MyActivity);
</code>

Затем в задачах onPostExecute я могу просто вызвать MyActivity.doX ();

C:

Третий способ - сделать асинктаску частным классом в самой деятельности, но мне бы очень хотелось, чтобы она была отдельной. Возможность повторного использования, а что нет & # x2013;

Есть мысли по этому поводу?

Подводя итог, нужно сделать doX () после завершения task.execute. Любые идеи приветствуются.

D:

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

<code>public class ProfileSettings extends Activity
{
      public static void doX()
      {
          //Logic...
      }
}
</code>

От AsyncTask

<code>MyActivity.doX();
</code>
Третий способ - сделать асинктаску частным классом в самой деятельности, но мне бы очень хотелось, чтобы она была отдельной. Resusability а что нет OVERTONE
У меня есть, сделай это снова. И снова, пока вы, наконец, не поняли. Cristian
ok D довольно глупо. Я просто выбрасываю иде OVERTONE
@ Cristian Какой полезный комментарий. Да, у меня есть OVERTONE
@ Cristian ИЛИ .... Я мог бы попросить о помощи, вместо того, чтобы ударить головой о стену, которая кажется твоим "стилем снова и снова". Задавая этот вопрос, я обнаружил концепцию анонимных внутренних классов в ответе Кабуко. Я решил свою проблему и стал более просвещенным для нее. Так что будьте добры заблудиться, если это самые продуктивные комментарии, которые вы можете сделать. OVERTONE

Ваш Ответ

4   ответа
6

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

CustomTask task = new CustomTask() {
    @Override
    protected void onPostExecute(Long result) {
        super.onPostExecute(result);
        MyActivity.this.doX();
    }
}.execute();
Вау. Я не знаю, будет ли это работать, но это довольно умно, независимо от того, OVERTONE
Это заняло немного времени, но я даже не думал о занятиях. Это не то, что я бы использовал в избытке, так как тогда это будет сбивать с толку, но для моей проблемы, это идеально. Я использую Asyncs OnPostExecute (так, как это было задумано), и мне не нужно передавать всю активность. Спасибо за это. Это довольно хитрость OVERTONE
Это очень помогло !!!) Спасибо !!!!!!!!!!!!!!! timonvlad
1

http: //howcanisolve.com/38646/android-java-equivalent-of-ios-block-callback

public interface ICallbacks { 
public void onResponse(JSONObject response);
public void onError(VolleyError error);
}

Затем в вашем обычном коде просто добавьте новый экземпляр Callbacks:

public static void getPassagesForFirebaseUser(FirebaseUser user,
Context context, ICallbacks events) { 
  //here code and call ICallbacks methods
  if(result){ events.onResponse(response); }
  if(error){ events.onError(err); }
}

в последнюю очередь вы можете вызвать метод с помощью:

getPassagesForFirebaseUser(user, context, new ICallbacks(){
  @Override
  public void onResponse(JSONObject response){
      //Success !!!
  }
  @Override
  public void onError(VolleyError response){
      //Error !!!
  }
});
2

Вариант A:

Android API уже предоставил встроенную функцию для этой цели AsyncTask.get ():

CustomTask task = new CustomTask();
task.execute(passedParams);
Result result = task.get(); // <- Block UI thread and waiting for AsyncTask finish.
this.doX(result);

Как видите, это плохая практика, поскольку она блокирует поток пользовательского интерфейса и может вызвать исключение ANR. Делая это, вы фактически жертвуете преимуществами AsyncTask и запускаете его синхронно с потоком пользовательского интерфейса.

Опция B и C:

Both - верный способ сделать что-то, вызывая метод doX () в методе onPostExecute (),

AsyncTask, как указано в его названии, запускает фоновый поток асинхронно с потоком пользовательского интерфейса, и после завершения фонового потока в потоке пользовательского интерфейса вызывается метод onPostExecute. Невозможно точно определить, когда вызывается метод onPostExecute (т.е. когда метод doInBackground завершен) во время сборки проекта, как это определяется во время выполнения приложения, единственное, что мы знаем, это то, что метод onPostExecute гарантированно вызывается в потоке пользовательского интерфейса. в какой-то момент в будущем, другими словами, при написании кода во время сборки проекта, мы никогда не узнаем точно, когда doInBackground завершится и выполнение кода перейдет обратно в поток пользовательского интерфейса вне метода onPostExecute (если вы не реализуете некоторый механизм ожидания в коде, подобном Option А). Таким образом, цель метода onPostExecute состоит в том, чтобы обрабатывать все после завершения метода doInBackground, поэтому единственный аргумент метода onPostExecute - это результат, возвращаемый методом doInBackground.

Разница между вариантом B и C заключается в том, следует ли реализовывать AsyncTask как внутренний класс или отдельный класс. Об этом много раз говорили и обсуждали в StackOverflow. Большинство людей думают, что хорошо разделять их по причинам, связанным с возможностью повторного использования или т. Д. С моей точки зрения, я не согласен с этим. Язык программирования Java имеет свою причину предоставлять синтаксис внутреннего класса для соответствия некоторым специальным ситуациям кодирования, когда речь идет о рефакторинге кода с точки зрения ООП, больше думайте об уровне абстракции проблемы, а не просто убирайте внутренний класс из класса Activity на уровне кода. Как вы можете видеть из своего примера, изолируя AsyncTask от Activity, вы не получаете никакой реальной выгоды, а наоборот увеличиваете сложность кода (требуется передать ссылку на контекст Activity между классами) для решения проблемы.

Я думаю, что реальный вопрос в том, должны ли мы изолировать реализацию внутреннего класса AsyncTask от Activity. Для лучшего рефакторинга ООП-кода (повторное использование, тестируемость и т. Д.) Ознакомьтесь с моим ответом в этомStackOverflow question чтобы увидеть, как правильно изолировать бизнес-уровень от уровня пользовательского интерфейса приложения.

0

нужно хранитьэкземпля вашейActivity (не только класс) вASyncTask. И еслиActivity уничтожается во время выполнения задачи (что если пользователь нажимает клавишу Назад button?), вам нужно сообщить об этом задаче, чтобы задача не пыталась вызвать метод на мертвомActivity.

А еслиActivity возвращается к жизни (например, после поворота экрана), затем вам нужно заново установить новыйActivity к текущей задаче.

С этими вещами все в порядке.

@ OVERTONE Это просто реальность, с которой вам придется столкнуться с приложениями для Android. Есть много способов, которыми активность может умереть, и вам просто нужно пройти через эту боль и учитывать ее, когда вы, к сожалению, имеете дело с AsyncTasks. Погрузчики в том числе AsyncTaskLoader а также LoaderManager сделай это немного лучше. kabuko
Хорошая точка зрения. Для моего приложения ориентация фиксирована, но вы никогда не знаете, когда это может измениться. Хммм .... OVERTONE

Похожие вопросы