Passing context from Service to AsyncTask without leaking it

You can try using a WeakReference and a static inner class for your AsyncTask to the object you are trying to access. Something like this:

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
            }
        }
    }
}

I have a Service from which I am starting AsyncTask from a given timer to do background tasks.

Don't use an AsyncTask. Use a thread. Or, better yet, used ScheduledExecutorService for the timing component, as that will execute tasks on a background thread. AsyncTask is only appropriate for when you need to do work on the main application thread when the background part is done, and that's rarely required with a service.

Also, bear in mind that your timer will stop working once your process terminates.

So my question is, how can I use context in my AsyncTask(top level class) without leaking it?

Call getApplicationContext() on the Service and use that Context.


You can pass a WeakReference in your AsyncTask, for example :

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();
}

Hope this helps.