Подтвердить что ты не робот

Передача контекста из сервиса в AsyncTask без утечки

У меня есть Service из которой я AsyncTask из заданного таймера для выполнения фоновых задач. Моя потребность требует коротких очередей сетевых задач, поэтому я и остаюсь с AsyncTask.

Из AsyncTask я выполняю ряд операций (таких как запуск уведомлений), которые требуют Context. Теперь, когда я инициализирую Context в моей AsyncTask, я получаю предупреждение "Это поле AsyncTask объект контекста".

Я видел несколько вопросов, касающихся одного и того же, но все они были связаны с Activity/Fragment. Итак, мой вопрос, как я могу использовать Context в моей AsyncTask (класс верхнего уровня), не пропуская его?

4b9b3361

Ответ 1

У меня есть Служба, из которой я запускаю AsyncTask из заданного таймера для выполнения фоновых задач.

Не используйте AsyncTask. Используйте поток. Или, еще лучше, использовал ScheduledExecutorService для компонента синхронизации, поскольку это будет выполнять задачи в фоновом потоке. AsyncTask подходит только тогда, когда вам нужно выполнять работу в основном потоке приложения, когда выполняется фоновая часть, и которая редко требуется для службы.

Кроме того, помните, что ваш таймер перестанет работать после завершения процесса.

Итак, мой вопрос: как я могу использовать контекст в моей AsyncTask (класс верхнего уровня) без его утечки?

Вызовите getApplicationContext() на Service и используйте Context.

Ответ 2

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

class MyServiceWhichDoesNotLeak extends Service {

    View view;
    AsyncTask task;

    //Your onCreate and stuff


    private static class BackgroundTask extends AsyncTask<Void, Void, String> {

        private final WeakReference<View> viewReference;

        public BackgroundTask(View view) {
            this.viewReference = new WeakReference<>(view);
        }

        @Override
        protected String doInBackground(Void... params) {
            // Background stuff
            return "something";
        }

        @Override
        protected void onPostExecute(String result) {
            View view = viewReference.get();
            if (view != null) {
                //Use your view
            }
        }
    }
}

Ответ 3

Вы можете передать WeakReference в AsyncTask, например:

public class MyAsynctask extends AsyncTask<Void, Void, Void> {

   private WeakReference<Context> mWeakContext;

   public MyAsynctask (WeakReference<Context> reference) {
        mWeakContext = reference;
   }

   // when you need context use mWeakContext.get();
}

Надеюсь это поможет.