Android上不可靠的网络(代码)

时间:2014-06-09 17:24:24

标签: android networking https

我在我开发的应用中遇到了一个问题 - 各种用户报告他们遇到了连接问题(仅限我的应用)。 例如:

  • 其他应用似乎可以访问互联网,但我的同时无法访问
  • 它仅适用于WiFi,但不适用于移动数据连接。

我的应用通过HttpUrlConnection(HTTPS)连接到基于REST的API。

我的一个错误是我真的无法知道用户手机上发生了哪些网络错误(错误消息表示通用的“无网络”)。 我已经实施了有限的重试以弥补这个问题,但我不知道其他可能出错的地方。

我的主要网络代码附在下面,我向所有有经验的网络程序员提问:

  1. 我的代码有问题吗?
  2. 是否真实地设置了超时? (连接/读取每个15秒)
  3. 向用户显示哪些最佳做法或网络错误的原因或在发布后对其进行诊断?
  4. - >请不要建议“使用HTTPClient而不是HttpUrlConnection”

    创建POST请求的代码:

    public static HTTPURLResponseHolder doHTTPPost(URL url, List<NameValuePair> headers, String body, String charset, boolean followRedirect,
            SSLContext context) throws IOException {
        HttpURLConnection connection = getConfiguredConnection(url, headers, charset, context, true);
    
        // WORKAROUND for recycling issue...
        // http://stackoverflow.com/questions/19258518/
        connection.setRequestProperty("Connection", "close");
    
        connection.setRequestMethod("POST");
        int contentLength = 0;
        if (body != null) {
            contentLength = body.getBytes().length;
        }
    
        try {
            connection.setFixedLengthStreamingMode(contentLength);
            BufferedOutputStream stream = null;
            try {
                OutputStream outputStream = null;
                if (body != null) {
                    outputStream = connection.getOutputStream();
                    stream = new BufferedOutputStream(outputStream);
                    stream.write(body.getBytes());
                    stream.flush();
                }
            } finally {
                close(stream);
            }
    
            InputStream inputStream = connection.getInputStream();
            HTTPURLResponseHolder holder = new HTTPURLResponseHolder();
    
            int responseCode = connection.getResponseCode();
            holder.setResponseCode(responseCode);
    
            // Normal case:
            String o = StreamUtility.inputStreamToString(inputStream, charset);
            close(inputStream);
            holder.setOutput(o);
            return holder;
        } catch (IOException e) {
            return handleIOException(url, headers, charset, false, context, connection);
        } finally {
            connection.disconnect();
        }
    }
    
    static HttpURLConnection getConfiguredConnection(URL url, List<NameValuePair> httpHeaders, String charset, SSLContext context, boolean doOutput)
            throws IOException {
        if (url == null || url.getProtocol() == null || !url.getProtocol().toLowerCase(Locale.US).startsWith("http")) {
            throw new IllegalArgumentException("Invalid HTTP URL: " + url);
        }
    
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setConnectTimeout(15000);
        connection.setReadTimeout(15000);
        connection.setDoInput(true); // Read
        if (doOutput) {
            connection.setDoOutput(doOutput);
        }
    
        // Workaround for older Android versions who do not do that automatically (2.3.5 for example)
        connection.setRequestProperty(HTTP.TARGET_HOST, url.getHost());
        connection.setRequestProperty("Accept-Encoding", charset);
    
        // Langauge
        String language = Locale.getDefault().getLanguage();
        if (StringUtility.isNullOrEmpty(language)) {
            language = Locale.US.getLanguage();
        }
        connection.setRequestProperty("Accept-Language", language);
    
        // Add the headers, if they exist
        if (httpHeaders != null) {
            for (NameValuePair nvp : httpHeaders) {
                if (nvp != null) {
                    connection.setRequestProperty(nvp.getName(), nvp.getValue());
                }
            }
        }
        return connection;
    }
    

0 个答案:

没有答案