1

我想在收到来自客户端的数据时显示一条消息。我启动了一个服务器和一个客户端。客户端从服务器发送和接收确认,但在服务器端 android 上,没有显示任何消息,并且应用程序崩溃了,在这里我粘贴了我从 log 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); 
        } 
    } 
} 

日志猫

   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)
4

6 回答 6

3

您的代码有两个问题。正如其他人所说,第一个是您正在从非 ui线程调用命令。尽管从您的代码中看不出来,但 logcat 建议您从非 ui线程调用它。为了显示Toast消息,您需要确保从 UI 线程中调用 toast。

另一个问题是您正在尝试Toast使用Application上下文显示。这将失败,因为应用程序上下文无法更新 UI。只需使用Activity上下文。

您对创建的调用Toast应修改为如下所示:

myContext.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(myContext, "msg msg", Toast.LENGTH_SHORT).show();
    }
});
于 2013-04-29T15:08:34.750 回答
0

看到更完整的代码后,很明显这个类的设计存在一些大问题。最明显的是它有两个构造函数,它们接受不同的对象,而忽略其他对象。因此,要么有一个null套接字,要么有一个null上下文。

其次,正如我在其他答案中发布的那样,Toast 的显示方式存在一些缺陷。

我建议您对该课程进行一些核心更改。首先,删除您的构造函数并添加它:

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

现在您可以构造一个实例,而不必担心有空对象。这也强制你使用Activity上下文构造 this - 所以你可以调用方法unOnUiThread,所以现在你可以调用:

((Activity) myContext).runOnUiThread(new Runnable() {
    @Override
    public void run() {
        Toast.makeText(myContext, "msg msg", Toast.LENGTH_SHORT).show();
    }
});
于 2013-04-29T16:48:42.693 回答
0

您只能显示来自 UI 线程的 toast。从另一个线程尝试它会导致崩溃。看看HandlersHandler.CallbacksMessages

HTH,马克

于 2013-04-29T14:49:18.543 回答
0

您不能在不是主 GUI 线程的线程中显示 toast。

您似乎选择了“处理程序”作为您正在编写的类的名称。您应该使用 android.os.Handler 在 GUI 线程中进行此操作,而不是您的。

此外,您的代码中似乎出现了 NullPointerException。你能告诉我们它发生在哪条线上吗?(编辑:代码中的哪一行是“Handler.java:49”)

于 2013-04-29T14:44:13.847 回答
0

我有同样的问题。当我在 UI 线程上调用代码时,问题为我解决了

public void showToastMessage(final String msg) {

    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(BaseActivity.this, msg, Toast.LENGTH_LONG).show();
        }
于 2017-09-04T09:12:36.623 回答
0

您甚至可以在没有 Activity 上下文的情况下执行此操作,如下所示:

new Handler(Looper.getMainLooper()).post( () -> 
    Toast.makeText(context, "Toast!", Toast.LENGTH_SHORT).show());
于 2022-02-28T19:08:00.723 回答