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");
}
最后提醒:不要在主线程中进行网络通信。