Не отображается тост сообщение Android

Я хочу отобразить сообщение при получении данных от клиента. Я запустил сервер и клиент. Клиент отправляет и получает подтверждение от сервера, но на стороне сервера Android не отображалось ни одного сообщения, и приложение зависало, и здесь я вставляю то, что я получил из журнала cat. а также внутренний класс, когда я хочу показать сообщение:

import android.widget.Toast;

class Handler implements Runnable { 
    private Context myContext; 

    private static final String TAG = "myLogs";

    public Handler(Socket client) { 
        this.client = client; 
    } 
    public Handler(final Context context) { 
        this.myContext= context; 
    } 

    public void run() { 
        try {
            //message received..

            Toast.makeText(myContext.getApplicationContext(), "msg msg", Toast.LENGTH_SHORT).show();
            Log.d(TAG, "received....");
        } catch (IOException e) { 
            System.out.println("Errore: " + e); 
        } 
    } 
} 

Logcat

   04-29 17:21:53.679: D/My log(19533): waiting for connnections   
   04-29 17:24:13.726: D/My Log(19533): Connected     04-29
   17:24:14.859:W/dalvikvm(19533): threadid=9: thread exiting with uncaught exception    (group=0x40018578)     04-29 17:24:14.859: E/AndroidRuntime(19533): FATAL EXCEPTION: Thread-10 04-29
   17:24:14.859: E/AndroidRuntime(19533): java.lang.NullPointerException     04-29
   17:24:14.859:E/AndroidRuntime(19533): at com.example.tcpserver.Handler.run(Handler.java:49)     04-29
   17:24:14.859: E/AndroidRuntime(19533): at java.lang.Thread.run(Thread.java:1019)

6 ответов

Решение

После просмотра более полного кода становится очевидным, что дизайн этого класса имеет некоторые серьезные проблемы. Наиболее очевидным является то, что он имеет два конструктора, которые принимают разные объекты и игнорируют другие. Таким образом, будет либо null сокет или null контекст.

Во-вторых, как я написал в своем другом ответе, есть некоторые недостатки в том, как отображается тост.

Я предлагаю вам внести некоторые основные изменения в этот класс. Для начала удалите ваши конструкторы и добавьте это вместо:

public Handler(Activity context, Socket client) { 
    this.client = client; 
    this.myContext= context; 
}

Теперь вы можете создать один экземпляр и не беспокоиться о нулевых объектах. Это также заставляет вас строить это с Activity контекст - так что вы можете вызвать метод unOnUiThread, так что теперь вы можете позвонить:

((Activity) myContext).runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(myContext, "msg msg", Toast.LENGTH_SHORT).show();
    }
});

Есть две вещи не так с вашим кодом. Во-первых, как уже говорили другие, вы вызываете команду из не-пользовательского потока. Хотя это не очевидно из вашего кода, logcat предполагает, что вы вызываете это из не-пользовательского потока. Для того, чтобы показать Toast сообщение, вам нужно убедиться, что вы вызываете тост из потока пользовательского интерфейса.

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

Ваш призыв к созданию Toast должно быть изменено, чтобы выглядеть так:

myContext.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(myContext, "msg msg", Toast.LENGTH_SHORT).show();
    }
});

Вы можете отображать только тосты из потока пользовательского интерфейса. Попытка этого из другого потока вызовет сбой. Посмотрите на Handlers, Handler.Callbacks и Messages.

HTH, Марк

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

public void showToastMessage(final String msg) {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(BaseActivity.this, msg, Toast.LENGTH_LONG).show();
        }

Вы не можете показать тост внутри потока, который не является основным потоком GUI.

Кажется, вы выбрали "Обработчик" в качестве имени для класса, который вы пишете. Вы должны использовать android.os.Handler, чтобы сделать это внутри потока GUI, а не у вас.

Кроме того, кажется, что вы получаете исключение NullPointerException в вашем коде. Можете ли вы сказать нам, по какой линии это происходит? (Изменить: какая строка "Handler.java:49" в вашем коде)

Вы даже можете сделать это без контекста действия, например:

      new Handler(Looper.getMainLooper()).post( () -> 
    Toast.makeText(context, "Toast!", Toast.LENGTH_SHORT).show());
Другие вопросы по тегам