【问题标题】:Are socket connection UI thread blocking in Android?Android中的套接字连接UI线程是否阻塞?
【发布时间】:2014-07-22 13:26:02
【问题描述】:

我是套接字编程的新手,我已经阅读了几篇教程以了解何时开始。但是我对Android UI Thread和socket编程还是知之甚少。

使用 HTTP 请求时,您应该在不同的线程中执行操作,以防止 UI 阻塞并获得 ANR。所以我的问题是套接字连接呢?它是否与 HTTP 请求一样工作,其中代码执行停止,直到设备得到响应,因此,我必须在后台线程中执行操作以防止 ANR?

【问题讨论】:

  • 使用HTTP请求与socket连接基本相同。一个 HTTP 请求建立一个 TCP 连接,然后发送一些可以被知道 HTTP 协议的程序理解的文本。因此,发送和接收数据包以及处理数据包数据将在工作时阻塞您的应用程序。这同样适用于套接字连接。因此,您应该始终在单独的线程中进行连接。编辑:我想不出在处理网络流量时不应该使用线程的任何应用程序(无论是否是 android),因此至少可以认为始终使用线程是一种好习惯。

标签: java android multithreading sockets


【解决方案1】:

是的,套接字连接和读取操作正在阻塞。

【讨论】:

    【解决方案2】:

    HTTP 请求使用 TCP 作为底层协议,因此它类似于使用套接字。在 Android 中,如果您将任何网络代码放在主线程上,您将收到此异常 NetworkOnMainThreadException

    这是一个关于如何在 Android 中安全地发出 HTTP 请求的示例:

    Thread  httpThread = new Thread(new Runnable() {
    
                                    @Override
                                    public void run() {
    
                                        try {
    
                                            HttpParams httpParameters = new BasicHttpParams();
                                            // Set the timeout in milliseconds until a connection is established.
                                            // The default value is zero, that means the timeout is not used. 
                                            int timeoutConnection = 5000;
                                            HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
                                            // Set the default socket timeout (SO_TIMEOUT) 
                                            // in milliseconds which is the timeout for waiting for data.
                                            int timeoutSocket = 7000;
                                            HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
    
                                            DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
                                            HttpResponse httpResponse = null;
    
                                            HttpPost httpPost = new HttpPost(url);
    
                                            httpResponse = httpClient.execute(httpPost);
    
                                            StatusLine statusLine = httpResponse.getStatusLine();
                                            int statusCode = statusLine.getStatusCode();
    
                                            System.out.println(statusCode);
                                            if (statusCode == 200) {
                                                //success
                                            }else{
                                                //fail
                                            }
    
                                        } catch (Exception exception) {
    
                                            Log.e("", exception.toString());
    
                                        }
                                    }
                                });
                                httpThread.start();
    

    【讨论】:

      【解决方案3】:

      对于 HTTP,您可以使用考虑到侦听器的异步 HTTP 库:http://loopj.com/android-async-http/

      对于 Sockets,你可以使用 AsyncTask 在后台做事:Using AsyncTask for android network connection

      你不能在主线程上进行网络连接,它会抛出一个异常,因为如果超时它会冻结应用程序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-04-13
        • 2012-06-13
        • 2017-04-18
        • 1970-01-01
        • 2012-01-05
        • 1970-01-01
        • 2013-07-20
        • 2016-07-15
        相关资源
        最近更新 更多