Java 如何在Android API 25中使用套接字/线程

Java 如何在Android API 25中使用套接字/线程,java,android,multithreading,sockets,android-7.0-nougat,Java,Android,Multithreading,Sockets,Android 7.0 Nougat,我对API 25中的套接字和线程有问题。我直接将API 25作为我的Nexus 6p 7.1.1的目标 当尝试在端口8124上与我的节点服务器通信时,我初始化了一个新线程并初始化了一个套接字,但我得到了networkonmainthreadexception public class MainActivity extends AppCompatActivity { private Socket socket; @Override protected void onCreate(Bundle

我对API 25中的套接字和线程有问题。我直接将API 25作为我的Nexus 6p 7.1.1的目标

当尝试在端口8124上与我的节点服务器通信时,我初始化了一个新线程并初始化了一个套接字,但我得到了networkonmainthreadexception

public class MainActivity extends AppCompatActivity {

private Socket socket;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

    StrictMode.setThreadPolicy(policy);

    Button LoginButton = (Button) findViewById(R.id.button2);
    LoginButton.setOnClickListener(
            new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    TryLogin(v);
                }
            }
    );
}

public void TryLogin(View v){
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                socket = new Socket("192.168.1.57", 8124);
                Log.i("SOCKET", "Was the thread started?");
            } catch(UnknownHostException e1){

            } catch (IOException e1){

            }
        }
    }).start();
}
}


当我调用start时,我从未看到线程是否已启动?。logcat中也没有抛出任何错误。但是,当我更改为运行时,会出现networkonmainthreadexception错误。好像有什么东西被改变了。我已经验证了到我的节点服务器的tcp连接是使用节点客户端显示的。

当您获得networkonmainthreadexception时,这意味着您的线程已正确启动,并且您的日志没有打印出来的唯一原因是打印前抛出了错误。将日志移动到套接字代码上方,如下所示,您将看到它正在打印:

Log.i("SOCKET", "Was the thread started?");
socket = new Socket("192.168.1.57", 8124);
现在知道线程已正确启动,您可以关注主要问题,即networkmainthreadexception

幸运的是,这个问题的答案如下:


希望这有帮助

当应用程序尝试在主线程中执行网络操作时,会引发此异常。在onViewCreated中使用以下代码以避免此错误,否则请在网络调用中使用AsynkTask

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

忽略线程策略我正在测试请完全删除StrictMode。当然,你不应该调用run,因为你已经看到它不再是线程了。当大家都攻击NetworkOnMainThreadException时,你的帖子相当混乱,下次你能这样写吗?,而你有一个SocketTimeoutException。好的,我现在收到日志消息,但我在节点控制台中没有看到连接。我也没有看到IoException或UnknowHostException上的e1.printStackTrace出现错误。您不是说引发了networkonmainthreadexception错误吗?您可以通过在异步任务中运行该套接字代码来修复此问题。更多信息可以在这里找到:添加另一个只记录和重试的异常捕获。我猜这将是一种不同于您捕获的两种异常类型。当我运行时,它抛出了主线程预期,但现在它记录了消息“我收到连接超时错误”,这很奇怪,因为我可以获得与节点客户端的连接,但不能从AsyncTask运行套接字代码并报告我认为results.AsyncTask或线程将是相同的。为什么会不同呢?如果android.os.Build.VERSION.SDK_INT>9,那么应该是android.os.Build.VERSION.SDK_INT<0.android.os.Build.VERSION.SDK_INT>9,因为由于蜂巢,您无法在主线程上进一步执行网络任务。是的,我知道。抱歉说不清楚。我建议<0,所以它永远不会被调用,因为我觉得使用这种模式很遗憾。