简体   繁体   中英

Show Toast inside AsyncTask

  public class ayncClass extends AsyncTask<String, Void, String> {

        public void onPreExecute(){


        }
        @Override
        protected String doInBackground(String... params) {
            HttpClient client = new DefaultHttpClient();
            HttpGet get = new HttpGet(URL HERE);
            try{
                HttpResponse responseGiven = client.execute(get);
                StatusLine statusLine = responseGiven.getStatusLine();
                int statusCode = statusLine.getStatusCode();
                if(statusCode == 404){
                    Toast.makeText(getApplicationContext(), "ERROR", Toast.LENGTH_SHORT).show();

                }
            } catch(Exception e){

            }
            return null;
        }

        public void onPostExecute(...){
            super.onPostExecute(s);

        }

    }

But when I debug and run the app, it does the get the Toast to show up. Is there a way to do actions withing the AsyncTask, while its working?

Thanks!

Toast belongs to UI.

We can only update UI in main thread (UI Thread).

AsyncTask.doInBackground() will never be called in main thread and that's the reason.

You should use my code from here :

public enum Toaster {
    INSTANCE;

    private final Handler handler = new Handler(Looper.getMainLooper());

    public void showToast(final Context context, final String message, final int length) {
        handler.post(
            new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(context, message, length).show();
                }
            }
        );
    }

    public static Toaster get() {
        return INSTANCE;
    }
}

Then you can do

Toaster.get().showToast(getApplicationContext(), "ERROR", Toast.LENGTH_SHORT);

This will run your code on the UI thread, and it will work.

This may help

onPreExecute() { // some code #1 }

 doInBackground() { runOnUiThread(new Runnable() { public void run() { // some code #3 (Write your code here to run in UI thread) } }); } onPostExecute() { // some code #3 } 

Toast is UI element , it is not coming because your application's UI runs on UI thread while doInBackground method of AsyncTask runs in different thread. Hence, whatever UI related operations you want to perform should be in onPostExecute or onPreExecute . If such a condition is there that you have to update UI in doInBackground ,you can use handler thread or best way, you can use runOnUiThread method and inside that you can add your toast.

try below

public class ayncClass extends AsyncTask<String, Void, String> {

    public void onPreExecute(){


    }
    @Override
    protected String doInBackground(String... params) {
        HttpClient client = new DefaultHttpClient();
        HttpGet get = new HttpGet(URL HERE);
        try{
            HttpResponse responseGiven = client.execute(get);
            StatusLine statusLine = responseGiven.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if(statusCode == 404){
                // Toast.makeText(getApplicationContext(), "ERROR", //Toast.LENGTH_SHORT).show();

            }
        } catch(Exception e){

        }
        return String.valueOf(statusCode ); // make this change
    }

    public void onPostExecute(String result){
        super.onPostExecute(s);
 Toast.makeText(getApplicationContext(), result, 
 Toast.LENGTH_SHORT).show();
    }

}

Place the Toast message alway in PostExecute method.

public void onPostExecute(...) { super.onPostExecute(s);

    Toast.makeText(context, "Hellooo I am at Post Execute method", Toast.LENGTH_SHORT).show();
    }

Toast can be shown only from UI thread. onPostExecute is called in the UI thread, so you can store statusCode in a member variable and check for 404 in the onPostExecute method and display the Toast there. Something like this:

public class ayncClass extends AsyncTask<String, Void, String> {

    private int mStatusCode;

    @Override
    protected String doInBackground(String... params) {
        HttpClient client = new DefaultHttpClient();
        HttpGet get = new HttpGet(URL HERE);
        try{
            HttpResponse responseGiven = client.execute(get);
            StatusLine statusLine = responseGiven.getStatusLine();
            mStatusCode = statusLine.getStatusCode();
        } catch(Exception e){
            // do NOT let catch blocks without log
            // if something bad happens you will never know
        }
        return null;
    }

    public void onPostExecute(...){
        super.onPostExecute(s);
        if(mStatusCode == 404){
            Toast.makeText(getApplicationContext(), "ERROR", Toast.LENGTH_SHORT).show();
        }
    }
}

Or simply pass the status code as a parameter to onPostExecute:

public class ayncClass extends AsyncTask<String, Void, Integer> {

    @Override
    protected Integer doInBackground(String... params) {
        HttpClient client = new DefaultHttpClient();
        HttpGet get = new HttpGet(URL HERE);
        try{
            HttpResponse responseGiven = client.execute(get);
            StatusLine statusLine = responseGiven.getStatusLine();
            return statusLine.getStatusCode();
        } catch(Exception e){
            // do NOT let catch blocks without log
            // if something bad happens you will never know
        }
        return -1;
    }

    public void onPostExecute(Integer statusCode){
        super.onPostExecute(s);
        if(statusCode == 404){
            Toast.makeText(getApplicationContext(), "ERROR", Toast.LENGTH_SHORT).show();
        }
    }
}

Simply when you must show something into your UI thread (for example the Toast message) then write:

runOnUiThread(new Runnable(){
    public void run() {
        //Interaction with UI (Toast message)
    }
});

You can not show toast in doInBackground function because doInBackground function does not work on UI Thread. You can publish progress to onProgressUpdate function. it will work on UI Thread .

public class ayncClass extends AsyncTask<String, Void, String> {

    private final Context context;

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

    public void onPreExecute(){


    }
    @Override
    protected String doInBackground(String... params) {
        HttpClient client = new DefaultHttpClient();
        HttpGet get = new HttpGet(URL HERE);
        try{
            HttpResponse responseGiven = client.execute(get);
            StatusLine statusLine = responseGiven.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            if(stat-usCode == 404){
            // you can not use toast in doInBackground function. you need to pass to progress
            publishProgress(0);
            }
        } catch(Exception e){

        }
        return null;
    }

    @Override
        protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        Toast.makeText(context, "ERROR", Toast.LENGTH_SHORT).show();
        }

    public void onPostExecute(...){
        super.onPostExecute(s);

    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM