Intereting Posts
Не удалось создать приложение com.android.tools.fd.runtime.BootstrapApplication? Запустить приложение из панели уведомлений в android Местоположение: Разрешение GPS / сети: требуется, если доступно Будет ли этот метод вызываться? (Все еще требуется принятый ответ … См. Подробности в ответе) Экспорт Android дает «Конверсия в формат Dalvik с ошибкой 1» Пользовательский значок дома в действии Бар Шерлок Иногда Fragment не привязан к Activity (onCreateOptionsMenu) Как создать структуру тестового каталога проекта в Android Studio? HTML5 Audio не может воспроизводиться через Javascript, если только он не запускается вручную WebViewCoreThread, используемый admob AdView, использует высокий CPU даже в том случае, если родительская активность приостановлена ​​ Камера: функция setDisplayOrientation не работает для Samsung Galaxy ACE с Android 2.3.6 Установить изображение после изменения ориентации Как вы можете использовать загрузчик, который является анимированным счетчиком с загрузчиками изображений, такими как Glide, Picasso и т. Д.? Программирование приложений Android в jython Android Fatal Signal 11

Что происходит с AsyncTask, когда запускающая активность остановлена ​​/ уничтожена, пока она еще запущена?

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

 public class MyActivity extends Activity { private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { protected Bitmap doInBackground(String... urls) { return DownloadImage(urls[0]); } protected void onPostExecute(Bitmap result) { ImageView img = (ImageView) findViewById(R.id.img); img.setImageBitmap(result); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); new DownloadImageTask().execute("http://mysite.com/image.png") } } 

Предположим, что действие приостановлено или уничтожено (возможно, два случая различны), в то время как DownloadImageTask все еще работает в фоновом режиме. Затем могут быть запущены методы DownloadImageTask , которые запускаются в потоке пользовательского интерфейса активности, и DownloadImageTask может попытаться получить доступ Методы деятельности (это внутренний класс, поэтому он может обращаться к методам и переменным экземпляра внешнего класса) с приостановленным или уничтоженным Управлением, например вызовом findViewByID в примере ниже .. что происходит? Это тихо проваливается? Вызывает ли это какое-либо исключение? Будет ли пользователь уведомлен о том, что что-то пошло не так?

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

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

Solutions Collecting From Web of "Что происходит с AsyncTask, когда запускающая активность остановлена ​​/ уничтожена, пока она еще запущена?"

Рассмотрите эту задачу (где R.id.test ссылается на действительное представление в макете моей деятельности):

 public class LongTaskTest extends AsyncTask<Void, Void, Void>{ private WeakReference<Activity> mActivity; public LongTaskTest(Activity a){ mActivity = new WeakReference<Activity>(a); } @Override protected Void doInBackground(Void... params) { LogUtil.d("LongTaskTest.doInBackground()"); SystemClock.sleep(5*60*1000); LogUtil.d("mActivity.get()==null " + (mActivity.get()==null)); LogUtil.d("mActivity.get().findViewById(R.id.frame)==null " + (mActivity.get().findViewById(R.id.test)==null)); return null; } } 

Если я запустил эту задачу из ActivityCreative Activity так:

 public class Main extends Activity { @Override public void onCreate(Bundle state) { super.onCreate(state); setContentView(R.layout.testlayout); new LongTaskTest(this).execute(); finish(); } } 

Независимо от того, как долго я сплю фоновый поток, мой журнал всегда показывает:

 LongTaskTest.doInBackground() mActivity.get()==null false mActivity.get().findViewById(R.id.frame)==null false 

Это означает, что активность и ее представления, похоже, остаются в живых (даже если я вручную выдаю GC через DDMS). Если бы у меня было больше времени, я бы посмотрел на дамп памяти, но в остальном я действительно не знаю, почему это так … но, отвечая на ваши вопросы, кажется, что:

  • Это тихо проваливается? нет
  • Вызывает ли это какое-либо исключение? нет
  • Будет ли пользователь уведомлен о том, что что-то пошло не так? нет

DoInBackground () будет продолжать работать, даже если ваша активность будет уничтожена (i, ваш основной поток будет уничтожен), потому что метод doInBackground () работает в потоке рабочего / фона. При запуске метода onPostExecute () будет выполняться «проблема», поскольку он запускается в потоке основного / пользовательского интерфейса, и вы можете столкнуться с несвязанными данными, но для пользователя не будет никаких исключений. Таким образом, всегда лучше отменить свою AsyncTask, когда ваша активность будет уничтожена, поскольку нет смысла запускать AsyncTask, когда активность больше не присутствует. Используйте службу Android, если вы постоянно хотите что-то загружать из сети, даже когда ваш компонент / действие будет уничтожен. Благодарю.