【问题标题】:Why AsyncTask to avoid "NetworkOnMainThreadException" is not working?为什么避免“NetworkOnMainThreadException”的 AsyncTask 不起作用?
【发布时间】:2016-02-06 05:49:31
【问题描述】:

尝试在作为客户端的 AndroidStudio-Java 应用程序与 Visual Studio C# 服务器之间实现一个简单的 UDP 客户端/服务器数据报。我完全确定服务器端正在工作。

Here 是一个 UDP 客户端,在 ButtonClick 上,一个 UDP 消息应该“暂时”发送到端口 15000 上的 localhost。

我的 StackTrace 弹出了 Android.os.NetworkOnMainThreadException 错误。我发现here 可以使用一个简单的解决方案,即导入 StrictMode 并将新策略设置为 permitAll()。但是我的应用程序仍然无法工作,并且 ButtonClick “没有异常跟踪 + 没有收到消息”实际上没有任何反应,这是我的代码:

        ButtonOne.setOnClickListener(
                    new Button.OnClickListener() {
                        public void onClick(View v) {
                            TextView TextOne = (TextView) findViewById(R.id.TestText);
                            TextOne.setText("Hi");

                            String host = "127.0.0.1"; // localhost
                            int port = 15000;
                            String message = "Test";
                            DatagramSocket dsocket = null;

                            if (android.os.Build.VERSION.SDK_INT > 9)
                            {
                                StrictMode.ThreadPolicy policy = 
                                        new StrictMode.ThreadPolicy.Builder().permitAll().build();
                                StrictMode.setThreadPolicy(policy);
                            }

                            try {
                                // Get the Internet address of the specified host
                                InetAddress address = InetAddress.getByName(host);

                                // wrap a packet
                                DatagramPacket packet = new DatagramPacket(
                                        message.getBytes(),
                                        message.length(),
                                        address, port);

                                // Create a datagram socket, send the packet through it, close it.
                                dsocket = new DatagramSocket();
                                dsocket.send(packet);
                                dsocket.close();
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
            );

然后我发现这里@9​​87654323@强烈不建议使用StrictMode,我需要使用AsyncTask。但是在Android Documentation 上,它说“AsyncTask 必须被子类化才能使用。子类将覆盖至少一个方法(doInBackground(Params ...)),并且通常会覆盖第二个方法(onPostExecute(Result) .)”我没有得到,因为每次我在 MainActivity 类中添加 Async 时都会出错,这很令人沮丧..

对这个简单的任务使用 StrictMode 不好吗?如果是,为什么它不起作用?如果否,谁能告诉我如何将 AsyncTask 导入这段代码?我应该使用 Params、Progress、Result 函数吗??

【问题讨论】:

    标签: java android udp client udpclient


    【解决方案1】:

    由于您的数据包是发送后忘记的,并且您不监控其进度或在其结束时执行某些操作,因此您不需要异步任务。您需要在新线程中启动网络活动。代码如下,可能有一些小的编译问题,因为我现在没有访问权限。

    ButtonOne.setOnClickListener(
                        new Button.OnClickListener() {
                            public void onClick(View v) {
                                TextView TextOne = (TextView) findViewById(R.id.TestText);
                                TextOne.setText("Hi");
    
    
                                String message = "Test";
                                Thread networkThread = new Thread() {
    
    
                                  String host = "127.0.0.1"; // localhost
                                  int port = 15000;
                                  DatagramSocket dsocket = null;
    
                                  public void run() {
                                    try {
                                    // Get the Internet address of the specified host
                                    InetAddress address = InetAddress.getByName(host);
    
                                    // wrap a packet
                                    DatagramPacket packet = new DatagramPacket(
                                            message.getBytes(),
                                            message.length(),
                                            address, port);
    
                                    // Create a datagram socket, send the packet through it, close it.
                                    dsocket = new DatagramSocket();
                                    dsocket.send(packet);
                                    dsocket.close();
                                  } catch (Exception e) {
                                    e.printStackTrace();
                                }//catch
                              }//run
                             };// Networkthread
                             networkThread.start();//networkThread.start()
                            }//onClick
                        }//onClickListener
                );//setOnClickListener
    

    【讨论】:

    • 此代码没有运行并弹出两个错误:“不兼容的类型:void 无法转换为 Thread”在 .start() 部分,然后“消息是从内部类中使用的,应该被宣布为最终”。一旦我将其声明为“最终”,整个线程就会变成红色,并显示“不兼容的类型:必需的 Java.Lang.Thread,找到:无效”。有什么建议吗?谢谢
    • 有效!注意事项:通过发送到本地 IP 不起作用 - 如果在同一台机器上使用 Android Studio 和 Visual Studio(服务器-客户端)。需要服务器的实际 IP。
    • 谢谢伙计。欣赏它:)。为什么没有人提及您的简单解决方案? “只需创建一个新线程”,您可以使用 AsyncTask 来完成吗?
    • 如果你在 doPostExecute() 中做了一些响应,或者如果你想发送一个大数据包并想在一个栏中显示它的进度,那么就需要异步任务,因为这样做是通过线程很麻烦。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-04
    • 2020-07-25
    • 2012-11-16
    • 2015-01-01
    • 1970-01-01
    • 2012-12-14
    • 2011-12-04
    相关资源
    最近更新 更多