13

I have a couple private AsyncTask methods that I'd like to break out into public external classes. In my application, I have a public class extending Application which holds some shared routines I want to access from different parts of my application. When I break out the AsyncTask class however, I'm no longer able to call getApplicationContext() to get a reference to my application library (the class does not inherit anything from Activity now). getBaseContext() will have problems as well. Should I be passing a context into the AsyncTask when it gets instantiated and build from there? Not sure if that was safe or not.

import java.util.ArrayList;
import android.os.AsyncTask;

public class DlTask extends AsyncTask
{
    long totalbytes = 0;
    long totalread = 0;
    ArrayList <String> data;

    @Override
    protected void onPreExecute ()
    {   
        AppLib lib = (AppLib) getApplicationContext();

        lib.saveStatusText ("Contacting " + lib.getServerAddress () + ":" + lib.getServerPort () + "...");
       super.onPreExecute ();
    }

      @Override
      protected Object doInBackground (Object... params)
      {
        data = lib.sendCommand (CMD_LIST);
         return true;
      }

      @Override
      protected void onPostExecute (Object result)
      {

         if (data != null)
         {
                    lib.saveStatusText (data.size () + " files found");
         }
         else
         {
            Log.d (TAG, "data is null");
            Toast.makeText (getBaseContext(), msg, Toast.LENGTH_SHORT).show ();                     
         }

         super.onPostExecute(result);
      }

}
alditis
  • 4,633
  • 3
  • 49
  • 76
wufoo
  • 13,571
  • 12
  • 53
  • 78

3 Answers3

13

Should I be passing a context into the AsyncTask when it gets instantiated and build from there?

You do not have a choice, as you will be unable to get a Context by any other means.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Can you elaborate @CommonsWare ? Why does `getApplicationContext()` not work from the UI portions of `AsyncTask` ? (ex: `onPreExecute()` or `onPostExecute()`) This link 'suggests' it can work, But my reality shows it will not compile (Sdk 8 -- 17); http://www.daniweb.com/software-development/mobile-development/threads/449375/how-to-get-context-in-asynctask – donfede Apr 21 '13 at 17:10
  • 2
    @donfede: " Why does getApplicationContext() not work from the UI portions of AsyncTask ?" -- because `getApplicationContext()` is a method on `Context`, and `AsyncTask` does not inherit from `Context`. – CommonsWare Apr 21 '13 at 17:22
  • 3
    won't this cause a leak if the activity is destroyed before the asynctask finishes? – MikeIsrael Dec 19 '13 at 12:29
  • 2
    @MikeIsrael: For the duration of the task, yes. `AsyncTask` is designed for short operations. Anything that would take longer than a second or so should be handled by some other means, such as an `IntentService`. – CommonsWare Dec 19 '13 at 12:31
  • @CommonsWare thanks, as always the concise but precise answers are appreciated. – MikeIsrael Dec 19 '13 at 14:31
1

You should do like this. In my case it works:

public class DlTask extends AsyncTask {
     private Context context;

     public DlTask(Context context) { this.context = context; }

     @Override
     protected void onPreExecute() {
         super.onPreExecute();
         ..........
     }

     @Override
     protected Object doInBackground (Object... params)
     {
        data = lib.sendCommand (CMD_LIST);

        return true;
     }

     @Override
     protected void onPostExecute (Object result)
     {

        if (data != null)
     {
         lib.saveStatusText (data.size () + " files found");
     }
     else
     {
        Log.d (TAG, "data is null");
        Toast.makeText (context, msg, Toast.LENGTH_SHORT).show ();              
        //You can use the CONTEXT like this (passing the context variable like parameter
     }

     super.onPostExecute(result);
  }
alditis
  • 4,633
  • 3
  • 49
  • 76
Rodrigo Xavier
  • 222
  • 2
  • 6
0

Either pass a Context in the constructor of your AsyncTask, or use a static variable in your Application class to access it (set sMyInstace = this;). The first solution is preferable though.

SimonSays
  • 10,867
  • 7
  • 44
  • 59