Почему Android не может освободить законченную активность из памяти после завершения AsyncTask? - PullRequest
0 голосов
/ 30 апреля 2019

Итак, я читал об утечках памяти в Android относительно AsyncTask, и, по сути, насколько я понял, это когда активность по какой-то причине разрушается, но AsyncTask не выполняется, так как AsyncTask имеет сильную ссылку на Activity, GC можетне собирает активность, т.е. не может освободить ее из памяти.У меня такой вопрос: если / когда AsyncTask завершает свою работу и больше не нужен, почему тогда GC не может собрать эту ссылку Activity?Почему это может быть проблемой?

1 Ответ

0 голосов
/ 30 апреля 2019

Как правило, внутренние классы часто переживают своих родителей, поэтому родительский класс не имеет права на GC.Что касается AsyncTask, если вы сделаете асинхронную задачу inner и предоставите ей контекст своей активности, Android Studio предупредит, что это может вызвать утечки памяти.

This AsyncTaskкласс должен быть статическим, иначе могут возникнуть утечки (анонимный android.os.AsyncTask). Статическое поле будет пропускать контексты.Нестатические внутренние классы имеют неявную ссылку на свой внешний класс.Если этот внешний класс является, например, Fragment или Activity, то эта ссылка означает, что долго выполняющийся обработчик / загрузчик / задача будет содержать ссылку на действие, которое не позволяет собирать мусор.Точно так же прямые полевые ссылки на действия и фрагменты из этих длительных экземпляров могут вызвать утечки.Классы ViewModel никогда не должны указывать на представления или контексты, не относящиеся к приложениям.

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

Решение?

Возможное решение - дать слабую ссылку на ваш контекст.Другое решение - отменить асинхронную задачу с помощью функции обратного вызова onStop () вашей активности.Более того, вы можете подтвердить состояние своей активности, используя activityContext.isFinishing().Если состояние равняется true, просто отмените или верните асинхронную задачу.

Немного не по теме.Асинхронные задачи остались в прошлом, есть и другие лучшие методы для обработки параллелизма, такие как RxJava, сопрограммы Котлина и т. Д.

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