Страницы

Поиск по вопросам

пятница, 3 января 2020 г.

Передача ссылки на Activity в AsyncTask, почему плохо и как можно было иначе

#java #android #android_asynctask


Всё что внизу описано, это то как я использовал интерфейс для получения результата
из  AsynckTack в главный поток, используя CallBack. Почему мне сказали, что плохо ,
что я передал ссылку на активити в AsyncTask? И как лучше надо было это исполнить?

Вот в классе MainActivity вызываю такой метод и как видите передаю ссылку на активити
в AsyncTack

private void UploadData() {
        String url = "https://qwerty.ru" ;
        AsyncUploadingData asyncUploadingData = new 
        AsyncUploadingData(this);
        asyncUploadingData.execute(url);
    }
}


В AsyncTack  вложен интерфейс 

interface AsyncResult {
        void getResult(String answer);
    }


Объявлен  private AsyncResult mCallback;

И в конструкторе принимаю ссылку на активити. И неявно привожу к интерфейсу(правильно
так выразиться?)

 AsyncUploadingData(AsyncResult mCallback) {
        this.mCallback = mCallback;
    }


И в опеределенный момент вызываю метод интерфейса, а интерфейс подключен в MainActivity 

 mCallback.getResult(answer);

    


Ответы

Ответ 1



Почему мне сказали, что плохо , что я передал ссылку на активити в AsyncTask? Хранение ссылки на активити в AsyncTask чревато тем, что в случае уничтожения переданной активити в момент работы асинстаска: а) Произойдет утечка памяти, так как GC не сможет убрать из памяти активити, так как на нее будет хранится ссылка (в случае с strong reference); б) Вызов методов активити, в лучшем случае, ни к чему не приведет, а в худшем – будут возникать ошибки. Первая проблема решается хранением активити в виде weak reference, однако вторая проблема остается. И как лучше надо было это исполнить? Существует большое количество способов решения данной проблемы. Например, можно воспользоваться лоадерами или retain-фрагментами (лоадеры сохраняют состояние как раз с помощью retain-фрагментов). Можно использовать различные библиотеки, например Chronos. Если используете MVP, то можно воспользоваться библиотекой Moxy, которая, в частности, решает возникшую у Вас проблему.

Ответ 2



Да особой разницы в целом нет, будь то интерфейс или прямая ссылка на Activity. Не советовали туда передавать Activity так как нарушает инкапсуляцию. Так-то, конечно же, можно передавать Activity, но хотя бы заворачивать её тогда уж в WeakReference. WeakReference mWeakActivity; public AsyncUploadingData(Activity activity) { mWeakActivity = new WeakReference(activity); } Но, независимо от подхода, при вызове из onPostExecute нужно проверять ссылку на null, так как к моменту завершения AsyncTack Activity уже могла быть пересоздана.

Комментариев нет:

Отправить комментарий