HttpURLConnection相关的小记

474 查看

HttpURLConnection相关的小记

在Android上进行网络通信,Android本身提供的手段是HttpClient和HttpURLConnection两种。其中HttpClient来自于Apache,拥有大量灵活的API。但出于一些原因Google自己开发了HttpURLConnection,并且建议从Froyo(Android 2.2,API level 8)开始使用HttpURLConnection。(相关博文, 需备梯子。)

如果这两个满足不了需求,可以考虑使用AsyncHttpClient和Volley。

既然官方这么建议,我也就乖乖地使用HttpURLConnection了。

基础

对HTTP协议有一定了解的前提下,使用HttpURLConnection并没有什么难点,基本看个代码也就明白得差不多了。

HttpURLConnection conn = null;
InputStream is = null;
try {
    URL url = new URL(/* 你要的url */);
    conn = (HttpURLConnection) url.openConnection();
    conn.setConnectTimeout(15000);
    conn.setReadTimeout(10000);
    conn.setRequestMethod("GET"); // 按需更换
    conn.setDoInput(true); // 设置此连接是否允许Input的flag
    // 同样还有setDoOutput(boolean)

    conn.connect();
    int responseStatus = conn.getResponseCode();
    is = conn.getInputStream(); // 获取InputStream
    // 做点什么
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (conn != null) {
        conn.disconnect();
    }
    AndroidUtil.IO.close(is);
}

你可以参考这里HttpURLConnection的文档来学习更多的内容。

Request参数

在进行网络请求时,尤其是在使用POST方法时,请求的参数相当重要。但HttpURLConnection中并没有直接设置参数的方法。

为此我查阅了下SO,可以参考这个回答来进行带有参数的POST请求。

至于GET方法,直接在url后跟上相应的参数即可。

为了方便起见,我将回答中的getQuery()方法改造了一下,使得可以根据请求方式来生成参数字符串。

/**
 * 将参数列表转换为HttpUrlConnection可用的参数字符串<br>
 * 参见http://stackoverflow.com/a/13486223/2369039
 *
 * @param method 进行Http连接的方式,值为GET或POST
 * @param params 请求的参数列表
 * @return 转换后的String
 * @throws UnsupportedEncodingException
 */
public static String getRequestQuery(String method, List<NameValuePair> params)
    throws UnsupportedEncodingException {

    StringBuilder result = new StringBuilder();
    boolean first = true;

    for (NameValuePair pair : params)
    {
        if (first) {
            first = false;
            if ("GET".equalsIgnoreCase(method))
                result.append("?");
        }
        else
            result.append("&");

        result.append(URLEncoder.encode(pair.getName(), "UTF-8"));
        result.append("=");
        result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
    }

    return result.toString();
} // end static method getRequestQuery

转换InputStream为String

返回Response后,时常会需要将Response中的内容转换成String。

似乎会经常使用到,所以我查找了下合适的方法后,将其写成了个可复用的方法,为自己省点心。

/**
 * 将InputStream中的数据读取为String<br>
 * 参见http://stackoverflow.com/a/309718/2369039
 *
 * @param is InputStream
 * @param bufferSize buffer大小
 * @param encoding String编码
 * @return 读取出来的String
 * @throws IOException
 */
public static String is2String(InputStream is, int bufferSize,String encoding)
        throws IOException {
    Reader reader = new InputStreamReader(is, encoding);
    char[] buffer = new char[bufferSize];
    StringBuilder out = new StringBuilder();

    int rsz;
    while ((rsz = reader.read(buffer, 0, bufferSize)) >= 0) {
        out.append(buffer, 0, rsz);
    }

    return out.toString();
}

/**
 * 以UTF-8编码读取InputStream为String
 * @param is InputStream
 * @return 读取出来的String
 * @throws IOException
 */
public static String is2String(InputStream is) throws IOException {
    return is2String(is, 50, "UTF-8");
}

最后提醒:不要在主线程中进行网络通信。