简体   繁体   English

在AsyncTask中显示Toast

[英]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. 但是,当我调试并运行该应用程序时,它确实会显示Toast。 Is there a way to do actions withing the AsyncTask, while its working? 有没有办法在AsyncTask工作时对其进行操作?

Thanks! 谢谢!

Toast belongs to UI. Toast属于UI。

We can only update UI in main thread (UI Thread). 我们只能在主线程(UI线程)中更新UI。

AsyncTask.doInBackground() will never be called in main thread and that's the reason. 永远不会在主线程中调用AsyncTask.doInBackground() ,这就是原因。

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. 这将在UI线程上运行您的代码,并且将起作用。

This may help 这可能会有所帮助

onPreExecute() { // some code #1 } onPreExecute(){//一些代码#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. Toast是UI元素,它不会出现,因为您的应用程序的UI在UI线程上运行,而AsyncTask doInBackground方法在不同的线程上运行。 Hence, whatever UI related operations you want to perform should be in onPostExecute or onPreExecute . 因此,您要执行的与UI相关的任何操作都应该在onPostExecuteonPreExecute 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. 如果存在这种情况,您必须在doInBackground更新UI, doInBackground可以使用处理程序线程或最佳方式,可以使用runOnUiThread方法,并且可以在其中添加吐司。

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. 将Toast消息始终放置在PostExecute方法中。

public void onPostExecute(...) { super.onPostExecute(s); 公共无效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. 只能从UI线程显示Toast 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. 在UI线程中调用了onPostExecute ,因此您可以将statusCode存储在成员变量中,并在onPostExecute方法中检查404,然后在onPostExecute显示Toast 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: 或者只是将状态代码作为参数传递给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: 仅当您必须向UI线程中显示某些内容(例如Toast消息)时,然后编写:

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. 您无法在doInBackground函数中显示吐司,因为doInBackground函数不适用于UI线程。 You can publish progress to onProgressUpdate function. 您可以将进度发布到onProgressUpdate函数。 it will work on UI Thread . 它将在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);

    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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