AsyncTask doInBackground не запускается

У меня проблема с классом AsyncTask. Кажется, моя задача перестает работать после создания 4 или 5 задач.

У меня есть 2 вида деятельности. MainActivity, которая содержит только кнопку, которая запускает второе действие под названием ImageActivity.

ImageActivity очень прост. Он получил onCreate, который устанавливает макет, а затем он запускает новую AsyncTask, которая загружает изображение из Интернета. Это работает отлично несколько раз. Но он внезапно перестает работать. Метод onPreExecute запускается каждый раз, но не метод doInBackground. Я попытался упростить doInBackground со спящим циклом, и то же самое происходит. Я не могу понять это поведение, поскольку asynctask отменяется и устанавливается в null в методе onDestroy. Поэтому каждый раз, когда я запускаю новую ImageActivity, я также создаю новую AsyncTask.

Я воссоздаю ImageActivity и задачу, нажав кнопку «Назад», а затем нажав кнопку «MainActivity».

Какие-нибудь идеи кто-нибудь? Я действительно борюсь с этим.

UPDATE: код, который запускает ImageActivity (внутри кнопки onClickListener)

Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); intent.setClassName(this, ImageActivity.class.getName()); startActivity(intent); 

Вышеприведенный код запускает эту операцию

  public class ImageActivity extends Activity { private AsyncTask<Void, Void, Void> task; public void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.main); task = new AsyncTask<Void, Void, Void>() { @Override protected void onPreExecute() { Log.d(TAG, "onPreExecute()"); } @Override protected Void doInBackground(Void... params) { Log.d(TAG, "doInBackground() -- Here is the download"); // downloadBitmap("http://mydomain.com/image.jpg") return null; } @Override protected void onPostExecute(Void res) { Log.d(TAG, "onPostExecute()"); if(isCancelled()){ return; } } }.execute(); } @Override protected void onDestroy() { super.onDestroy(); task.cancel(true); } } 

ОБНОВИТЬ:

Я тестировал, используя комбинацию традиционных потоков Threads и runOnUiThread, и, похоже, он работает лучше. Теперь поток запускается каждый раз.

Solutions Collecting From Web of "AsyncTask doInBackground не запускается"

Кажется, что удаление AsyncTask и использование традиционного потока вместо объединения его с runOnUiThread . Но я до сих пор не нашел причины, почему AsyncTask настолько «нестабилен».

Вот код, который работает для меня:

 public class ImageActivity extends Activity { private Thread worker; public void onCreate(Bundle bundle) { super.onCreate(bundle); setContentView(R.layout.main); worker = new Thread(new Runnable(){ private void updateUI(final List<Object> list) { if(worker.isInterrupted()){ return; } runOnUiThread(new Runnable(){ @Override public void run() { // Update view and remove loading spinner etc... } }); } private List<Object> download() { // Simulate download SystemClock.sleep(1000); return new ArrayList<Object>(); } @Override public void run() { Log.d(TAG, "Thread run()"); updateUI(download()); } }); worker.start(); } @Override protected void onDestroy() { super.onDestroy(); worker.interrupt(); } } 

Я столкнулся с подобной проблемой. Вы не можете запускать несколько Asynctasks параллельно до SDK 11. Проверьте здесь дополнительную информацию

Я просто столкнулся с этой проблемой. Если вы используете AsyncTask.execute , ваша задача запускается в последовательной очереди (из источника Android 4.3):

При первом вводе AsyncTasks выполнялись последовательно на одном фоновом потоке. Начиная с DONUT, это было изменено на пул потоков, позволяющий нескольким задачам работать параллельно. Начиная с HONEYCOMB, задачи выполняются в одном потоке, чтобы избежать общих ошибок приложений, вызванных параллельным выполнением.

Это соответствует поведению, которое я видел. У меня AsyncTask появилось диалоговое окно doInBackground и заблокировано, пока диалог не был закрыт. В диалоговом окне понадобилась своя AsyncTask для завершения. Метод AsyncTask.doInBackground диалогового AsyncTask.doInBackground никогда не выполнялся, потому что исходная AsyncTask все еще была заблокирована.

Решение состоит в том, чтобы выполнить вторую AsyncTask в отдельном Executor .

Используйте traceview для исследования – или получите дамп потока. Я предполагаю, что один из ваших потоков AsyncTask зависает при загрузке.

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

Вот быстрый тест, который вы можете запустить – в 4.3, я вижу, что у меня есть только 5 одновременных потоков, которые я могу запустить. Когда один поток выходит, запускаются другие потоки.

  private void testAsyncTasks() { for (int i = 1; i <= 10; i++) { final int tid = i; new AsyncTask<Integer, Void, Void>() { protected void onPreExecute() { Log.d("ASYNCTASK", "Pre execute for task : " + tid); }; @Override protected Void doInBackground(Integer... args) { int taskid = args[0]; long started = SystemClock.elapsedRealtime(); Log.d("ASYNCTASK", "Executing task: " + taskid + " at " + started); for (int j = 1; j <= 20; j++) { Log.d("ASYNCTASK", " task " + taskid + ", time=" + (SystemClock.elapsedRealtime() - started)); SystemClock.sleep(1000); } return null; } protected void onPostExecute(Void result) { Log.d("ASYNCTASK", "Post execute for task : " + tid); }; }.execute(i); } } 

Вам не нужно беспокоиться о том, что домохозяйство работает на Android, поскольку оно управляется системой.

Также отправьте способ загрузки изображения. Вы также пытались не отменить нить в методе onDestroy ()? Как вы возвращаете изображение в поток пользовательского интерфейса?

Проблема, которую я считаю, связана с задачей загрузки тяжелых изображений. Даже если вы отмените асинхронную задачу, загрузка изображения продолжит выполнение, и задача async не будет завершена до завершения загрузки. Вы можете проверить метод isCancelled () на AyncTask во время загрузки и убить загрузку, если задача отменена.

Для справки, heres документация по методу cancel (): пытается отменить выполнение этой задачи. Эта попытка потерпит неудачу, если задача уже завершена, уже отменена или не может быть отменена по какой-либо другой причине. В случае успеха, и эта задача не началась при вызове отмены, эта задача никогда не должна выполняться. Если задача уже запущена, параметр mayInterruptIfRunning определяет, должен ли поток, выполняющий эту задачу, прерваться при попытке остановить задачу. Вызов этого метода приведет к вызову onCancelled (Object) в потоке пользовательского интерфейса после возврата doInBackground (Object []). Вызов этого метода гарантирует, что onPostExecute (Object) никогда не вызывается. После вызова этого метода вы должны периодически проверять значение, возвращаемое isCancelled (), из doInBackground (Object []), чтобы завершить задачу как можно раньше.

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