1

I am trying to post a toast from an async task and was reading this answer on stack:

Raising a Toast From AsyncTask

Quick summary of that questions leads to this:

Get the Context object by calling getApplicationContext() from MainActivity and pass it as a parameter to your AsyncTask

I am confused on how to pass a context through async task and how to call it:

my async task is:

public class ReadLogInJSON extends AsyncTask<String, Void, String>
{
    @Override
    protected String doInBackground(String... arg0) {
        // TODO Auto-generated method stub
        return readJSONFeed(arg0[0]);
    }

    protected void onPostExecute(String result)
    {
        //decode json here
        try{
            JSONObject json = new JSONObject(result);
            String status = json.getString("status");

            if(status == "no"){
                //toast logIN failed
                String message = "Log In Failed";
                Toast.makeText(this,  message, Toast.LENGTH_SHORT).show();
            }
            else {
                //get userName
                //get user ID
                //set preferences
                //launch normal activity
            }
        }
        catch(Exception e){
        }
    }

    public String readJSONFeed(String URL) {
        StringBuilder stringBuilder = new StringBuilder();
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(URL);
        try {
            HttpResponse response = httpClient.execute(httpGet);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if (statusCode == 200) {
                HttpEntity entity = response.getEntity();
                InputStream inputStream = entity.getContent();
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(inputStream));
                String line;
                while ((line = reader.readLine()) != null) {
                    stringBuilder.append(line);
                }
                inputStream.close();
            } else {
                Log.d("JSON", "Failed to download file");
            }
        } catch (Exception e) {
            Log.d("readJSONFeed", e.getLocalizedMessage());
        }
        return stringBuilder.toString();
    }
}

And I call it with this:

new ReadLogInJSON().execute(url);
Community
  • 1
  • 1
Mike
  • 6,751
  • 23
  • 75
  • 132

3 Answers3

1

You are trying to toast in onPostExecute which runs on the main thread so you do not need to pass context to your task. You should be able to do this:

Toast.makeText(MyActivity.this,  message, Toast.LENGTH_SHORT).show();

You could also use getApplicationContext()

Toast.makeText(getApplicationContext(),  message, Toast.LENGTH_SHORT).show();
Larry McKenzie
  • 3,253
  • 25
  • 22
  • Can you tell me where you are calling your task from? Also what you mean by they don't work... They throw an error? They don't compile? – Larry McKenzie Jun 22 '13 at 02:17
  • Can you confirm status doesn't equal "no" and the toast isn't bypassed? – Larry McKenzie Jun 22 '13 at 02:18
  • I am calling the task from a button pressed in my main activity. It does compile but show the toast. As for the if statement I will move it before it right now for testing to be sure. BRB – Mike Jun 22 '13 at 02:23
  • Ok it works it was my if statement acting whacky, which I will ask about in another stack question. Thanks! – Mike Jun 22 '13 at 02:24
  • http://stackoverflow.com/questions/17246771/odd-if-statement-in-android-with-reading-json – Mike Jun 22 '13 at 02:31
0

Call it like this

ReadLogInJSON task = new ReadLogInJSON(this);  // pass Context here to constructor
task .execute(url);

and create a constructor in your AsyncTask like this

  public class ReadLogInJSON extends AsyncTas <String, Void, String> {

  Context c;

  public ReadLogInJSON(Context context)
  {
      c = context;  // assign Context in constructor here
  }

  @Override1
  protected String doInBackground(String... arg0) {
    // TODO Auto-generated method stub
    return readJSONFeed(arg0[0]);

then change your Toast in onPostExecute() to this

 Toast.makeText(c,  message, Toast.LENGTH_SHORT).show();

Toast needs a Context so you pass your Activitys Context through the constructor and use that to display your Toast

There is never a reason or want to call getApplicationContext() from an Activity for a Toast. A Toast needs an Activity Context which an Activity obviously already has and is what this refers to

codeMagic
  • 44,549
  • 13
  • 77
  • 93
0

One thing that you should try, and IMO, it's good programming practice anyways is that if you need a Context object then you should declare that in the constructor for your AsyncTask subclass instead of using the empty constructor inherited from the parent class. If your doInBackground() function executes successfully then you should drop down into onPostExecute(). Try logging something at the end of your doInBackground() and at the start of your onPostExecute() so that you know you completed one callback and transitioned into the next in the flow.

In that case, your code would look more like:

public class ReadLogInJSON extends AsyncTask<String, Void, String> {
    private Context mContext;
    public ReadLoginJSON(Context context) {
        this.mContext = context;
    }

    @Override
    protected String doInBackground(String... arg0) {
        // TODO Auto-generated method stub
        return readJSONFeed(arg0[0]);
    }

    @Override
    public void onPostExecute(String result){
       // DO YOUR THING HERE
       Toast.makeText(this.mContext, "I Executed!", Toast.LENGTH_SHORT).show();
}
David C. Sainte-Claire
  • 2,461
  • 1
  • 15
  • 12