Asynctask doInBackgound () не работает, если уже запущена асинтеза

Когда пользователь входит в мое приложение. Я asynctask для поддержания сеанса пользователя. И эта задача async работает неограниченно, пока пользователь не выйдет из системы. Моя проблема в том, что когда я пытаюсь запустить другие asynctasks , их doInBackground() никогда не выполняется.

Я где-то читал, что если задача async уже запущена, мы не можем запускать новую async task . Я могу подтвердить это, потому что, когда я удалил задачу асинхронного сеанса пользователя, он работал правильно. Есть ли обходной путь?

PS: Я уже использовал executeOnExecutor() . Но это не помогло.

Для потенциально длительных операций я предлагаю вам использовать Service а не asynctask .

Запуск службы при входе пользователя в систему

 Intent i= new Intent(context, YourService.class); i.putExtra("KEY1", "Value to be used by the service"); context.startService(i); 

И остановите службу, когда пользователь выйдет из системы

 stopService(new Intent(this,YourService.class)); 

Чтобы узнать больше о Service вы можете сослаться на этот

Сервис: разработчики Android

Сервис: Vogella

Чтобы узнать больше об asynctask vs service вы можете обратиться к этому

Android: AsyncTask vs Service

Когда использовать Сервис или AsyncTask или Обработчик?

Я где-то читал, что если задача async уже запущена, мы не можем запускать новую задачу async.

Да, это факт, что вы не можете запустить более 5 (пять) AsyncTask в то же время ниже API 11, но для более да вы можете использовать executeOnExecutor .

AsyncTask использует шаблон пула потоков для запуска материала из doInBackground() . Первоначально проблема (в ранних версиях ОС Android) размер пула был всего 1, что означает отсутствие параллельных вычислений для группы AsyncTasks. Но позже они исправили это, и теперь размер 5, поэтому максимум 5 AsyncTasks могут выполняться одновременно.

Я выяснил некоторые правила Threading, и я нашел одно основное правило ниже,

 The task can be executed only once (an exception will be thrown if a second execution is attempted.) 

Что такое определение AsyncTask ?

AsyncTask обеспечивает правильное и простое использование потока пользовательского интерфейса. Этот класс позволяет выполнять фоновые операции и публиковать результаты в потоке пользовательского интерфейса без необходимости манипулировать потоками и / или обработчиками.

Как и где его использовать?

AsyncTask разработан как вспомогательный класс вокруг Thread и Handler и не представляет собой общую структуру потоков. AsyncTasks в идеале следует использовать для коротких операций (максимум за несколько секунд). Если вам нужно поддерживать потоки в течение длительных периодов времени, настоятельно рекомендуется использовать их.

Почему вы не можете одновременно использовать несколько AsyncTask ?

Для правильного функционирования этого класса необходимо соблюдать несколько правил потоковой передачи:

  • Класс AsyncTask должен быть загружен в поток пользовательского интерфейса . Это делается автоматически с JELLY_BEAN.
  • Экземпляр задачи должен быть создан в потоке пользовательского интерфейса.
  • execute(Params...) должен быть вызван в потоке пользовательского интерфейса.
  • Не вызывайте onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) вручную.
  • Задача может быть выполнена только один раз (исключение будет выбрано при попытке выполнить второе выполнение).

  • Одновременно запустить несколько AsyncTasks – невозможно?

  • Испытательный образец параллельного выделения AsyncTasks

Попробуйте Исполнитель

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

 Executor executor = anExecutor; executor.execute(new RunnableTask1()); executor.execute(new RunnableTask2()); ... 
  • Пример примера 1
  • Пример примера 2

Как и некоторые другие, я возражаю против предпосылки вопроса.

Основная проблема заключается в том, что вы используете AsyncTask для выполнения задачи за ее пределами. Другие это тоже отметили. Те, кто предлагает решения, которые могут смягчить вашу проблему через потоки низкого уровня (даже java.util.Concurrent является низкоуровневым, поэтому Scala использует актеров Akka в качестве абстракции), Service и т. Д. Довольно умны, но они обрабатывают Симптомом, а не лечить болезнь.

Что касается того, что вы должны делать, вы не первый, кто хочет поддерживать сеанс пользователя в приложении для Android. Это решенная проблема. В этих решениях общая нить (без каламбура) предназначена для использования SharedPreferences . Вот простой пример этого. Этот пользователь переполнения стека объединяет SharedPreferences с OAuth, чтобы сделать что-то более сложное.

В разработке программного обеспечения часто решают проблемы, предотвращая их в первую очередь. Я думаю, вы можете решить проблему одновременной работы AsyncTask s, не запуская одновременно AsyncTask s. Управление сеансом пользователей – это просто не то, для чего предназначена AsyncTask .

Если вы разрабатываете API 11 или выше, вы можете использовать AsyncTask.executeOnExecutor() позволяя запускать сразу несколько AsyncTasks.

http://developer.android.com/reference/android/os/AsyncTask.html#executeOnExecutor(java.util.concurrent.Executor, Params …)

Я поделюсь с вами, что мы делаем в нашем приложении.

Чтобы сохранить сеанс пользователя (мы используем OAuth с токенами доступа / обновления), мы создаем Singleton в расширенном классе Application . Почему мы объявляем этот Singleton внутри класса MainApplication? (Это название нашего класса), потому что ваша жизнь Синглтона будет привязана к Деятельности, которая ее создала , поэтому, если ваше приложение работает на низкой памяти, а сборщик мусора собирает ваши приостановленные действия, он освободит ваш экземпляр Singleton, потому что он связан К этой деятельности.

Создание его внутри вашего класса Application позволит ему жить в вашей RAM, пока пользователь продолжает использовать ваше приложение.

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

Да, начиная с двух или более асинтактов одновременно могут возникнуть проблемы на некоторых устройствах. Я пережил этот вопрос несколько месяцев назад. Я не мог предсказать, когда вторая асинхронная программа не сможет выполнить. Проблема была прерывистой, вызванной использованием памяти, поскольку я выполнял код ndk в asynctask. Но я хорошо помню, что это зависело от памяти устройства.

Аналогичный вопрос был задан раньше. Я бы опубликовал ссылку на аналогичный вопрос.

AsyncTask.executeOnExecutor () до уровня API 11

Некоторые пользователи предлагают обратиться за Service . Мой совет еще не идет по этому пути. Использование сервиса намного сложнее. Даже если вы пользуетесь сервисом, вам все равно придется иметь дело с потоками, поскольку

Обратите внимание, что службы, как и другие объекты приложения, запускаются в основном потоке их процесса хостинга. Это означает, что если ваша служба будет делать какие-либо интенсивные работы с ЦП (например, воспроизведение MP3) или блокирование (например, сетевые), она должна создать свою собственную нить, в которой для этой работы …

Если мы сможем решить проблему элегантным способом, не идите сложным способом.

Я бы предположил, что попробуйте один из API-интерфейсов в java.util.concurrent как это предлагается ниже

AsyncTask разработан как вспомогательный класс вокруг Thread и Handler и не представляет собой общую структуру потоков. AsyncTasks в идеале следует использовать для коротких операций (не более нескольких секунд). Если вам нужно поддерживать потоки в течение длительных периодов времени, настоятельно рекомендуется использовать различные API, предоставляемые java.util.concurrent pacakge, такие как Исполнитель, ThreadPoolExecutor и FutureTask.

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

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

Для получения дополнительной информации см. http://developer.android.com/guide/components/services.html , раздел. Если вы используете сервис или поток?