Тост не будет отображаться, прежде чем пытаться / поймать Thread.sleep () - PullRequest
3 голосов
/ 18 октября 2011

У меня возникает любопытная проблема, когда я пытаюсь show(); мои тосты. Ниже вы увидите два тоста, разделенных try/catch and Thread.sleep();. В этом случае появится второй тост, toast2, но не будет toast1.

Если я уберу try/catch, то оба тоста появятся без проблем.

Я видел в других местах на SO, что toast.show(); делает запрос в потоке пользовательского интерфейса, который может конфликтовать с другими операциями. Мне интересно, если это та же проблема, что у меня здесь с 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 ]

8 голосов
/ 18 октября 2011

В реальной жизни у вас, вероятно, будет какая-то логика вместо просто "сна", верно?Правильный способ запуска службы для 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 голос
/ 18 октября 2011

Поскольку вы приостанавливаете поток пользовательского интерфейса сразу после первого тоста, у него нет шансов быть отображенным.И к тому времени, когда сон закончится, время для первого тоста прошло.

Это звучит как наиболее правдоподобное объяснение, но я могу ошибаться.Нужно действительно глубоко копаться в коде Android, чтобы узнать наверняка.

0 голосов
/ 23 апреля 2017

Я столкнулся с той же проблемой, я попытаюсь решить ее с помощью AsyncTask, как это было предложено, но мой вариант использования следующий:

1) Я хочу отобразить сообщение Toast (начать широковещательное сообщение) 2) Если условие правильное, я передаю сообщение1 клиентам.3) Я сплю 2 секунды, чтобы закончить трансляцию.4) Я постоянно транслирую message2 клиентам.5) Если бы это было сделано, я бы выполнил еще одно сообщение (широковещательная рассылка завершена)

Я предложил следующий пример обходного решения (хотя последовательность, к которой относятся тост-сообщения, все еще отображалась в обратном порядке):

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);
    }
}
0 голосов
/ 18 октября 2011

Я предполагаю, что вам нужно создать тост, который длится более 2 секунд (почему вы должны использовать Thread.Sleep(2000) перед отправкой другого тоста?).
Итак, я только что нашел эту ссылку , которая дает очень хороший пример.
Надеюсь, это поможет

...