尝试/ catch Thread.sleep()之前不会显示Toast

时间:2011-10-18 04:05:16

标签: android sleep toast

当我尝试show();我的祝酒词时,我遇到了一个奇怪的问题。您将在下面看到两个以try/catch and Thread.sleep();分隔的Toast。在这种情况下,第二个Toast toast2将会显示,但toast1将不显示。

如果我删除try/catch两个Toasts将显示没有问题。

我在其他地方看到toast.show();在UI线程上发出请求,这可能会被其他操作冲突。我想知道这是否与我Thread.sleep();问题有同样的问题我如何解决这个问题?

谢谢

TestService.java

    ///Debug - Show a Toast
    // Toast does NOT show up
    Toast toast1 = Toast.makeText(context,"Service Started", Toast.LENGTH_SHORT);
    toast1.show();

    //Try to sleep for roughly 2 seconds
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    //Debug - Shows a Toast
    Toast toast2 = Toast.makeText(context,"Sleep completed", Toast.LENGTH_SHORT);
    toast2.show();

4 个答案:

答案 0 :(得分:8)

在现实生活中,你可能会有一些逻辑而不仅仅是“睡觉”,对吗? 正确的android方式,根据您的示例,启动服务将通过在工作线程上执行它。这将确保您不会得到ANR。

你的看起来像是:

    new AsyncTask<Void, Void, Void>() {

        @Override
        protected void onPostExecute(Void result) {
            Toast toast2 = Toast.makeText(context, "Sleep completed",
                    Toast.LENGTH_SHORT);
            toast2.show();
        }

        @Override
        protected void onPreExecute() {
            Toast toast1 = Toast.makeText(context, "Service Started",
                    Toast.LENGTH_SHORT);
            toast1.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            // Try to sleep for roughly 2 seconds
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;

        }

    }.execute();

答案 1 :(得分:1)

由于您在第一次吐司后立即暂停ui线程,因此不会  有机会被展示。到睡眠结束时,首先是时间 吐司已经过去了。

这听起来似乎是最合理的解释,但我可能错了。需要深入挖掘Android 代码,以确定。

答案 2 :(得分:0)

我假设您需要创建一个持续时间超过2秒的Toast(为什么在发送另一个Toast之前应该使用Thread.Sleep(2000)?)。
所以我刚发现this link提供了一个非常好的例子 希望这有帮助

答案 3 :(得分:0)

我遇到了同样的问题,我将按照建议使用AsyncTask尝试解决,但我的用例如下:

1)我想显示Toast消息(开始广播消息) 2)如果条件合适,我向客户广播message1。 3)我睡2秒钟以完成广播。 4)我一直向客户广播message2。 5)如果它完成了,我会Toast另一条消息(广播消息已完成)

我已经提出了以下解决方案示例(尽管toast消息的序列仍然反向显示):

package com.toasttester;

import android.os.Handler;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import android.os.AsyncTask;

public class MainActivity extends ActionBarActivity {
    Handler handler = new Handler();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        PreSleepToast pst = new PreSleepToast();
        pst.execute();
        Toast t = Toast.makeText(getApplicationContext(), "Message1", Toast.LENGTH_SHORT);
        t.show();
        try {
            Thread.sleep(2000);//to allow broadcasting to complete
        } catch (Exception e) {
            e.printStackTrace();
        }
        callToast1();
    }
    private Runnable r = new Runnable() {
        @Override
        public void run() {
            Toast t = Toast.makeText(getApplicationContext(), "Message3", Toast.LENGTH_SHORT);
            t.show();
        }
     };

    public class PreSleepToast extends AsyncTask<Void, byte[], Void> {
        /**
         * The sender socket on which we send connections.
         */
        public PreSleepToast() {
        }

        /**
         * Polling loop for outgoing connections.
         */
        @Override
        protected Void doInBackground(Void... params) {
            handler.post(r);
            return null;
        };
    };

    public void callToast1(){
        Toast t = Toast.makeText(getApplicationContext(), "Message2", Toast.LENGTH_SHORT);
        t.show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}