Вопрос по android – Как отобразить тост внутри обработчика / потока?

6

Я хочу отобразить тост, как только сообщение отправлено в сокет. После этого "Log.d (" ClientActivity "," C: отправлено ");"

Нужно ли создавать отдельную ветку для отображения Toast?

public class ClientActivity extends Activity {
private Handler handler = new Handler();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.client);
    serverIp = (EditText) findViewById(R.id.EditText01);
    message =(EditText) findViewById(R.id.EditText02);
    connectPhones = (Button) findViewById(R.id.Button01);

}

    public void Click1(View v) {
        if (!connected) {
            serverIpAddress = serverIp.getText().toString();
            if (!serverIpAddress.equals("")) {
                Thread cThread = new Thread(new ClientThread());
                cThread.start();
            }
        }
    }


private class ClientThread implements Runnable {

    public void run() {
        try {
            InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
            Log.d("ClientActivity", "C: Connecting...");
            Socket socket = new Socket(serverAddr, ServerActivity.SERVERPORT);
            connected = true;
            while (connected) {
                try {
                    if(i>5)
                    {


                    } 
                    else
                    {   
                        Log.d("ClientActivity", "C: Sending command.");
                        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket
                                .getOutputStream())), true);
                        // where you issue the commands
                        message1= message.getText().toString();
                        out.println(message1);
                        i=i+1;
                        Log.d("ClientActivity", "C: Sent.");
                    }    
                } catch (Exception e) {
                    Log.e("ClientActivity", "S: Error", e);
                }
            }
            socket.close();
            Log.d("ClientActivity", "C: Closed.");
        } catch (Exception e) {
            Log.e("ClientActivity", "C: Error", e);
            connected = false;
        }
    }
}

}

Ваш Ответ

4   ответа
3
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        System.out.println("I'm in handler");
        Toast.makeText(YourActivity.this, "This is a toast", Toast.LENGTH_SHORT).show(); 
    }
}, 1000);             
Если контекст представляет собой активность (как вы подразумевали под YourActivity.this), вы можете просто использовать runOnUiThread (), верно?
Не забудьте вызвать .show () на созданном тосте.
@DavidDoria вы правы, так как обработчик используется только для внесения любых изменений в пользовательский интерфейс, и когда вы видите реализацию метода runOnUiThread, он сначала проверяет, является ли текущий поток пользовательским или нет, а если текущий поток не является пользовательским потоком, то он выполняет заданную задачу в обработчике.
1

Сначала объявите глобальный обработчик,

Handler handler=null;

Затем создайте обработчик в вашем onCreate () следующим образом:

Handler handler=new Handler()
{
  public void handleMessage(Message msg)
{
  if(msg.what==0)
{
   Toast.makeText(ClientActivity.this,"Your Toast Mesage Goes here",Toast.LENGTH_LONG).show();
}

}
};

И теперь в вашем классе Runnable добавьте эту строку после"Log.d("ClientActivity", "C: Sent.");"

handler.sendEmptyMessage(0);

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

2

ет доступа кgetApplicationContext() что вы передаете это. Вы каким-то образом должны установить связь с потоком пользовательского интерфейса (т.е. основным потоком).
 Поэтому, когда вы хотите что-нибудь выпить, сделайте это вhandler.Post(Runnable) метод. Обработчикmiddle man между потоком пользовательского интерфейса и отдельным потоком, который вы работаете. Все операции пользовательского интерфейса должны быть выполнены вhandler.Post(Runnable)& APOS; srun() метод.

Так что в своей деятельности для отображения тоста сделайте следующее:

private class ClientThread implements Runnable {

    public void run() {
        try {
            InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
             .....
             .....
              message1= message.getText().toString();
                        out.println(message1);
                        i=i+1;
                        Log.d("ClientActivity", "C: Sent.");
                        handler.post(new Runnable(){
                          public void run()
                          {
                             Toast.make(....);
                           }
                         });

Не забудьте объявить и инициализировать объект-обработчик в вашей основной деятельности (вне потока)

handler=new Handler();
18

  runOnUiThread(new Runnable() {
                 public void run() {

                     Toast.makeText(ClientActivity.this,"asdf",Toast.LENGTH_LONG).show();
                }
            });

после этой строки

  Log.d("ClientActivity", "C: Connecting...");
У меня тот же код ... и он работает ... см. Редактирование я сделал ..
@ Шан, вы, вероятно, передаете неправильный контекст. Дважды проверьте, что вы передаете правильный контекст, а не только «this».
Он по-прежнему выдает сообщение об ошибке "Метод makeText (Context, CharSequence, int) в типе Toast не применим для аргументов (new Runnable () {}, String, int) & quot; Shan
Для дальнейшего использования: при вызове тоста из runnable ВСЕГДА пишите ActivityName.this или явно подразумеваете контекст (из класса вне действия для экземпляра). Просто напишите & this "quot; this & quot; заставляет Android (и Android Studio) думать, что вы имеете в виду Runnable, а не активность (и, следовательно, не контекст). Это то же самое, что и в случае с вложенным классом: вызывать & quot; this & quot; не относится к деятельности, в которой находится вложенный класс; это относится к вложенному классу и, следовательно, не к контексту. То же самое с Runnable.
в чем ошибка?

Похожие вопросы