Android下的两种http通信机制介绍

    Android网络通信经常会用到http通信机制,而基本上目前有两个实现方式:HttpUrlConnection和HttpClient。

HttpUrlConnection和HttpClient的关系

在研究一些开源网络请求框架时发现在Android 2.3及以上版本,使用的是HttpURLConnection,而在Android 2.2及以下版本,使用的是HttpClient。后来查阅资料发现Google官方在Android 2.3以后更推荐使用HttpURLConnection来在Android下进行Http通信。

联系

大多数的Android应用程序都会使用HTTP协议来发送和接收网络数据,而Android中主要提供了两种方式来进行HTTP操作,HttpURLConnection和HttpClient。这两种方式都支持HTTPS协议、以流的形式进行上传和下载、配置超时时间、IPv6、以及连接池等功能。

区别

1.HttpClient是apache的开源实现,而HttpUrlConnection是安卓标准实现,安卓SDK虽然集成了HttpClient,但官方支持的却是HttpUrlConnection;

2.HttpUrlConnection直接支持GZIP压缩;HttpClient也支持,但要自己写代码处理;我们之前测试HttpUrlConnection的GZIP压缩在传大文件分包trunk时有问题,只适合小文件,不过这个BUG后来官方说已经修复了;

3.HttpUrlConnection直接支持系统级连接池,即打开的连接不会直接关闭,在一段时间内所有程序可共用;HttpClient当然也能做到,但毕竟不如官方直接系统底层支持好;

4.HttpUrlConnection直接在系统层面做了缓存策略处理,加快重复请求的速度。

具体实现


首先Android下访问网络需要在Manifest文件内加上以下访问网络的权限

<uses-permission android:name="android.permission.INTERNET"/>  

通过HttpUrlConnection来GET数据

/**
 * 通过HttpUrlConnection来get请求数据
 * 
 * @param url
 * @return result
 */
public static String getByHttpUrlConn(String requestUrl) {
        StringBuffer strBuf;

        strBuf = new StringBuffer();
        try {
            URL url = new URL(requestUrl);
            URLConnection conn = url.openConnection();
            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));// 转码。
            String line = null;
            while ((line = reader.readLine()) != null)
                strBuf.append(line + " ");
            reader.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return strBuf.toString();
    }

通过HttpUrlConnection来POST数据

/**
 * 通过HttpUrlConnection来post请求数据
 * 
 * @param url
 * @return result
 */
public static String postByHttpUrlConn(String url) {
    String result = null;
    HttpURLConnection urlConnection = null;  
try {  
    urlConnection = (HttpURLConnection) new URL(url).openConnection();  
    urlConnection.setDoInput(true);  
    urlConnection.setDoOutput(true);  
    urlConnection.setChunkedStreamingMode(0);  
    urlConnection.setRequestMethod("POST");  
    urlConnection.setRequestProperty("Content-Type", ("application/xml; charset=utf-8").replaceAll("\\s", ""));  
    urlConnection.setRequestProperty("Content-Length", String.valueOf(Xml.getBytes().length));  
    OutputStream out = urlConnection.getOutputStream();  
    out.write(Xml.getBytes());  
    out.close();  
    int responseCode = urlConnection.getResponseCode();  
    InputStream in = null;  
    if (responseCode == 200) {  
        in = new BufferedInputStream(urlConnection.getInputStream());  
    } else {  
        in = new BufferedInputStream(urlConnection.getErrorStream());  
    }  
    result = readInStream(in);  
} catch (MalformedURLException e) {  
    e.printStackTrace();  
} catch (IOException e) {  
    e.printStackTrace();  
} finally {  
    urlConnection.disconnect();  
} 
    return result;
}

默认的,不给urlConnection添加任何属性的话是使用Get方法,如果用Post可以:urlConnection.setDoOutput(true);
urlConnection.setRequestMethod(“POST”);

当然还可以用setRequestProperty方法给请求添加:Host,Content-Type,Content-Lenth,Authentication等参数再使用Post的时候还有一个注意点在官方文档中提及的:上传数据到服务器时为了达到最好的性能,你可以在知道数据固定大小长度的情况下使用 setFixedLengthStreamingMode(int) 方法,或者在不知道长度的情况下使用setChunkedStreamingMode(int)。因为如果不这样的话,HttpURLConnection 在发生请求之前是将数据全部放到内存里面的,这样浪费内存(会造成OutOfMemoryError)而且延时。这个东西再这里详细说了:http://www.mzone.cc/article/198.html

通过HttpClient来GET数据

public static String getByHttpClient(String baseUrl){
    String result = null;
    //先将参数放入List,再对参数进行URL编码  
    List<BasicNameValuePair> params = new LinkedList<BasicNameValuePair>();  
    params.add(new BasicNameValuePair("param1", "中国"));  
    params.add(new BasicNameValuePair("param2","value2"));  
    //对参数编码  
    String param = URLEncodedUtils.format(params, "UTF-8");  
    //将URL与参数拼接  
    HttpGet getMethod = new HttpGet(baseUrl + "?" + param);  
    HttpClient httpClient = new DefaultHttpClient();  
    try {  
        HttpResponse response = httpClient.execute(getMethod); //发起GET请求  
        Log.i(TAG, "resCode = " + response.getStatusLine().getStatusCode()); //获取响应码  
        result = EntityUtils.toString(response.getEntity(), "utf-8");
    } catch (ClientProtocolException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    } catch (IOException e) {  
        // TODO Auto-generated catch block  
        e.printStackTrace();  
    }  
    return result;
}

通过HttpClient来POST数据

public static String postByHttpClient(String url){
    String result = null;
    //先将参数放入List,再对参数进行URL编码  
    List<BasicNameValuePair> params = new LinkedList<BasicNameValuePair>();  
    //和GET方式一样,先将参数放入List  
    params = new LinkedList<BasicNameValuePair>();  
    params.add(new BasicNameValuePair("param1", "Post方法"));  
    params.add(new BasicNameValuePair("param2", "第二个参数"));  

    try {  
        HttpPost postMethod = new HttpPost(url);  
        HttpClient httpClient = new DefaultHttpClient();  
        //将参数填入POST Entity中  
        postMethod.setEntity(new UrlEncodedFormEntity(params, "utf-8")); 

        HttpResponse response = httpClient.execute(postMethod); //执行POST方法  
        Log.i(TAG, "resCode = " + response.getStatusLine().getStatusCode()); //获取响应码  
        //获取响应内容  
        result = EntityUtils.toString(response.getEntity(), "utf-8"); 

    } catch (UnsupportedEncodingException e) {  
         // TODO Auto-generated catch block  
         e.printStackTrace();  
    } catch (ClientProtocolException e) {  
         // TODO Auto-generated catch block  
         e.printStackTrace();  
    } catch (IOException e) {  
         // TODO Auto-generated catch block  
         e.printStackTrace();  
    }   
        return result;
}

Ending

以上部分代码我没有实际运行测试,如果有问题,请留言评论
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值