专栏名称: 安卓开发精选
伯乐在线旗下账号,分享安卓应用相关内容,包括:安卓应用开发、设计和动态等。
目录
相关文章推荐
开发者全社区  ·  国产仿制药又被曝光了 ·  2 天前  
开发者全社区  ·  刘亦菲妈妈的三段婚姻 ·  2 天前  
开发者全社区  ·  华为人的春节反噬:老家亲戚都来借钱 ·  3 天前  
开发者全社区  ·  清华美女失落的十年 ·  3 天前  
51好读  ›  专栏  ›  安卓开发精选

Android 网络编程(2): HttpClient与HttpURLConnection

安卓开发精选  · 公众号  · android  · 2016-08-18 08:21

正文

(点击 上方公众号 ,可快速关注)


来源:刘望舒

链接:blog.csdn.net/itachi85/article/details/51010109



前言


上一篇我们了解了HTTP协议原理,这一篇我们来讲讲Apache的HttpClient和Java的HttpURLConnection,这两种都是我们平常请求网络会用到的。无论我们是自己封装的网络请求类还是第三方的网络请求框架都离不开这两个类库。


1.HttpClient


Android SDK中包含了HttpClient,在Android6.0版本直接删除了HttpClient类库,如果仍想使用则解决方法是:


  • 如果使用的是eclipse则在libs中加入org.apache.http.legacy.jar

    这个jar包在:**sdk\platforms\android-23\optional目录中(需要下载android

    6.0的SDK)

  • 如果使用的是android studio则 在相应的module下的build.gradle中加入:


android {

useLibrary 'org.apache.http.legacy'

}


HttpClient的GET请求


首先我们来用DefaultHttpClient类来实例化一个HttpClient,并配置好默认的请求参数:


//创建HttpClient

private HttpClient createHttpClient () {

HttpParams mDefaultHttpParams = new BasicHttpParams ();

//设置连接超时

HttpConnectionParams . setConnectionTimeout ( mDefaultHttpParams , 15000 );

//设置请求超时

HttpConnectionParams . setSoTimeout ( mDefaultHttpParams , 15000 );

HttpConnectionParams . setTcpNoDelay ( mDefaultHttpParams , true );

HttpProtocolParams . setVersion ( mDefaultHttpParams , HttpVersion . HTTP_1_1 );

HttpProtocolParams . setContentCharset ( mDefaultHttpParams , HTTP . UTF_8 );

//持续握手

HttpProtocolParams . setUseExpectContinue ( mDefaultHttpParams , true );

HttpClient mHttpClient = new DefaultHttpClient ( mDefaultHttpParams );

return mHttpClient ;

}


接下来创建HttpGet和HttpClient,请求网络并得到HttpResponse,并对HttpResponse进行处理:


private void useHttpClientGet ( String url ) {

HttpGet mHttpGet = new HttpGet ( url );

mHttpGet . addHeader ( "Connection" , "Keep-Alive" );

try {

HttpClient mHttpClient = createHttpClient ();

HttpResponse mHttpResponse = mHttpClient . execute ( mHttpGet );

HttpEntity mHttpEntity = mHttpResponse . getEntity ();

int code = mHttpResponse . getStatusLine (). getStatusCode ();

if ( null != mHttpEntity ) {

InputStream mInputStream = mHttpEntity . getContent ();

String respose = converStreamToString ( mInputStream );

Log . i ( "wangshu" , "请求状态码:" + code + "\n请求结果:\n" + respose );

mInputStream . close ();

}

} catch ( IOException e ) {

e . printStackTrace ();

}

}


converStreamToString方法将请求结果转换成String类型:


private String converStreamToString ( InputStream is ) throws IOException {

BufferedReader reader = new BufferedReader ( new InputStreamReader ( is ));

StringBuffer sb = new StringBuffer ();

String line = null ;

while (( line = reader . readLine ()) != null ) {

sb . append ( line + "\n" );

}

String respose = sb . toString ();

return respose ;

}


最后我们开启线程访问百度:


new Thread ( new Runnable () {

@Override

public void run () {

useHttpClientGet ( "http://www.baidu.com" );

}

}). start ();


请求的返回结果,请求状态码为200,结果就是个html页,这里只截取了部分html代码:



GET请求的参数暴露在URL中,这有些不大妥当,而且URL的长度也有限制:长度在2048字符之内,在HTTP 1.1后URL长度才没有限制。一般情况下POST可以替代GET,接下来我们来看看HttpClient的POST请求。


HttpClient的POST请求


post请求和get类似就是需要配置要传递的参数:


private void useHttpClientPost ( String url ) {

HttpPost mHttpPost = new HttpPost ( url );

mHttpPost . addHeader ( "Connection" , "Keep-Alive" );

try {

HttpClient mHttpClient = createHttpClient ();

List postParams = new ArrayList ();

//要传递的参数

postParams . add ( new BasicNameValuePair ( "username" , "moon" ));

postParams . add ( new BasicNameValuePair ( "password" , "123" ));

mHttpPost . setEntity ( new UrlEncodedFormEntity ( postParams ));

HttpResponse mHttpResponse = mHttpClient . execute ( mHttpPost );

HttpEntity mHttpEntity = mHttpResponse . getEntity ();

int code = mHttpResponse . getStatusLine (). getStatusCode ();

if ( null != mHttpEntity ) {

InputStream mInputStream = mHttpEntity . getContent ();

String respose = converStreamToString ( mInputStream );

Log . i ( "wangshu" , "请求状态码:" + code + "\n请求结果:\n" + respose );

mInputStream . close ();

}

} catch ( IOException e ) {

e . printStackTrace ();

}

}


2.HttpU RLConnection


Android 2.2版本之前,HttpURLConnection一直存在着一些令人厌烦的bug。比如说对一个可读的InputStream调用close()方法时,就有可能会导致连接池失效了。那么我们通常的解决办法就是直接禁用掉连接池的功能:


private void disableConnectionReuseIfNecessary () {

// 这是一个2.2版本之前的bug

if ( Integer . parseInt ( Build . VERSION . SDK ) Build . VERSION_CODES . FROYO ) {

System . setProperty ( "http.keepAlive" , "false" );

}

}


所以在Android 2.2版本以及之前的版本使用HttpClient是较好的选择,而在Android 2.3版本及以后,HttpURLConnection则是最佳的选择,它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。另外在Android 6.0版本中,HttpClient库被移除了,HttpURLConnection则是以后我们唯一的选择。


HttpURLConnection的POST请求


因为会了HttpURLConnection的POST请求那GET请求也就会了,所以我这里只举出POST的例子

首先我们创建一个UrlConnManager类,然后里面提供getHttpURLConnection()方法用于配置默认的参数并返回HttpURLConnection:


public static HttpURLConnection getHttpURLConnection ( String url ){

HttpURLConnection mHttpURLConnection = null ;

try {

URL mUrl = new URL ( url );

mHttpURLConnection = ( HttpURLConnection ) mUrl . openConnection ();

//设置链接超时时间

mHttpURLConnection . setConnectTimeout ( 15000 );

//设置读取超时时间

mHttpURLConnection . setReadTimeout ( 15000 );

//设置请求参数

mHttpURLConnection . setRequestMethod ( "POST" );

//添加Header

mHttpURLConnection . setRequestProperty ( "Connection" , "Keep-Alive" );

//接收输入流

mHttpURLConnection . setDoInput ( true );

//传递参数时需要开启

mHttpURLConnection . setDoOutput ( true );

} catch ( IOException e ) {

e . printStackTrace ();

}

return mHttpURLConnection ;

}


因为我们要发送POST请求,所以在UrlConnManager类中再写一个postParams()方法用来组织一下请求参数并将请求参数写入到输出流中:


public static void postParams ( OutputStream output , List paramsList ) throws IOException {

StringBuilder mStringBuilder = new StringBuilder ();

for ( NameValuePair pair : paramsList ){

if ( ! TextUtils . isEmpty ( mStringBuilder )){

mStringBuilder . append ( "&" );

}

mStringBuilder . append ( URLEncoder . encode ( pair . getName (), "UTF-8" ));

mStringBuilder . append ( "=" );

mStringBuilder . append ( URLEncoder . encode ( pair . getValue (), "UTF-8" ));

}

BufferedWriter







请到「今天看啥」查看全文


推荐文章
开发者全社区  ·  国产仿制药又被曝光了
2 天前
开发者全社区  ·  刘亦菲妈妈的三段婚姻
2 天前
开发者全社区  ·  华为人的春节反噬:老家亲戚都来借钱
3 天前
开发者全社区  ·  清华美女失落的十年
3 天前
我要WhatYouNeed  ·  来租我吧,想被人陪着并不羞耻 | 人群
7 年前