3

I have 2 .java files : AnswerActivity.java

public class AnswerActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_answer);

        new JSONTask().execute("https://example.com/api.php");
    }
}

and JSONTask.java

public class JSONTask extends AsyncTask<String, String, String> {

    @Override
    protected String doInBackground(String... params) {

    //--- some code cut here ---//

    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);

        Intent i = new Intent(this, AnswerActivity.class);
        Toast.makeText(i, result, Toast.LENGTH_LONG).show();
    }
}

my last 2 lines always gives me error :

    Intent i = new Intent(this, AnswerActivity.class);
    Toast.makeText(i, result, Toast.LENGTH_LONG).show();

I want to display the result into AnswerActivity as a Toast. but why I always get this error message?

Error:(68, 20) error: no suitable constructor found for Intent(JSONTask,Class<AnswerActivity>)
constructor Intent.Intent(String,Uri) is not applicable
(argument mismatch; JSONTask cannot be converted to String)
constructor Intent.Intent(Context,Class<?>) is not applicable
(argument mismatch; JSONTask cannot be converted to Context)

Error:(69, 14) error: no suitable method found for makeText(Intent,String,int)
method Toast.makeText(Context,CharSequence,int) is not applicable
(argument mismatch; Intent cannot be converted to Context)
method Toast.makeText(Context,int,int) is not applicable
(argument mismatch; Intent cannot be converted to Context)

what did I miss here? thank you

Saint Robson
  • 5,475
  • 18
  • 71
  • 118
  • 1
    Have a look at this answer: http://stackoverflow.com/a/4823947/4350275 . You need something like this. – Prerak Sola Jan 26 '17 at 15:47
  • 1
    I would advise you not to do any UI stuff from your AsyncTask. Pass in a JobDoneListener interface or something and call back to your activity when it's completed, then call the Toast there. That way you can do whatever UI manipulation you want after the AsyncTask is completed (not just a Toast). – MSpeed Jan 26 '17 at 15:55

5 Answers5

5

You need a context to show a Toast. Usually it's the Activity or the Fragment having the context. But since your AsyncTask is not a inner class of your AnswerActivity you have no reference to a context. So you could pass the Activity in the constructor and use that

public class JSONTask extends AsyncTask<String, String, String> {

    private Context context;

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

    @Override
    protected void onPostExecute(String result) {
        Toast.makeText(context, result, Toast.LENGTH_LONG).show();
    }
}

And use it with

new JSONTask(this)... // and so on

The big advantage of this is, that you do not keep a reference to the Activity and just pass the Context - since Activity does extend the Context.

Murat Karagöz
  • 35,401
  • 16
  • 78
  • 107
  • Beware with this. If your JSONTask can live longer than the lifecycle of the Activity (for example if you have a slow connection and you close the app) this will cause a memory leak. https://possiblemobile.com/2013/06/context/ – MSpeed Jan 26 '17 at 16:08
2

Remove this:

    Intent i = new Intent(this, AnswerActivity.class);
    Toast.makeText(i, result, Toast.LENGTH_LONG).show();

With this:

Pass Context in AsyncTask class:

public class JSONTask extends AsyncTask<String, String, String> {
private Context context;
//in constructor:
public JSONTask(Context context){
    this.context=context;
}

@Override
protected String doInBackground(String... params) {

//--- some code cut here ---//

}

@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);


    Toast.makeText(context, result, Toast.LENGTH_LONG).show();
}
}

And use this in Activity:

new JSONTask(AnswerActivity.this).execute("https://example.com/api.php");
W4R10CK
  • 5,502
  • 2
  • 19
  • 30
2

Your JSONTask should be

public class JSONTask extends AsyncTask<String, String, String> {

    Context mContext;

    public JSONTask(Context mContext) {
        this.mContext = mContext;
    }

    @Override
    protected String doInBackground(String... params) {
        //--- some code cut here ---//
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        Toast.makeText(mContext, result, Toast.LENGTH_LONG).show();
    }
}

Initialization

 new JSONTask(this).execute("https://example.com/api.php");
alex samsung
  • 110
  • 1
  • 10
0

If you are not using JSONTask class anywhere else then you can define it within your AnswerActivity as an inner class. If you do that then this code should work,

Toast.makeText(AnswerActivity.this, result, Toast.LENGTH_LONG).show();

Otherwise you have to pass your application context to the JSONTask and use that within Toast.

public class JSONTask extends AsyncTask<String, String, String> {

    private Context appContext;

    public JSONTask(Context context){
        this.appContext= context;
    }

    @Override
    protected String doInBackground(String... params) {

    //--- some code cut here ---//

    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);    
        Toast.makeText(appContext, result, Toast.LENGTH_LONG).show();
    }
}
Abhishek Jain
  • 3,562
  • 2
  • 26
  • 44
0

The better approach is create a constructor in the class

Context context;

public void init(Context ctx){
       this.context = ctx;
}

Then you can create the Toast

Toast.makeText(this.context, result, Toast.LENGTH_LONG).show();
MikeKeepsOnShine
  • 1,730
  • 4
  • 23
  • 35