在实际开发中,有的时候需要频繁的网络请求,而网络请求的方式很多,最常见的也就那么几个。本篇文章对常见的网络请求库进行一个总结。
一、使用HttpUrlConnection:
1. HttpUrlConnection
最开始学android的时候用的网络请求是HttpUrlConnection,当时很多东西还不知道,但是在android2.2及以下版本中HttpUrlConnection存在着一些bug,所以建议在android2.3以后使用HttpUrlConnection,之前使用HttpClient。
注:在Android2.2版本之前,HttpClient拥有较少的bug,因此使用它是最好的选择。而在Android2.3版本及以后,HttpURLConnection则是最佳的选择。它的API简单,体积较小,因而非常适用于Android项目。压缩和缓存机制可以有效地减少网络访问的流量,在提升速度和省电方面也起到了较大的作用。对于新的应用程序应该更加偏向于使用HttpURLConnection,因为在以后的工作当中我们也会将更多的时间放在优化HttpURLConnection上面。
2. HttpUrlConnection特点
- 比较轻便,灵活,易于扩展
- 在3.0后以及4.0中都进行了改善,如对HTTPS的支持
- 在4.0中,还增加了对缓存的支持
3. HttpUrlConnection用法:
(1)首先我们需要获取到一个HttpURLConnection实例,一般需要new出一个URL对象,并传入目标网络地址,通过调用openConnection()方法获得HttpURLConnection实例。
(2)得到该实例后。我们需要设置一下http请求的的方法,这里我们主要研究get和post,默认是使用get方法。get一般用于从服务器获取数据,post一般用于向服务器提交数据,设置请求方法使用函数setRequestMethod(“POST”)进行设置。
(3)此外可以进行一些请求的限制,比如连接超时的时间等,可以通过setConnectTimeout设置超时时间。
(4)获取服务器返回的输入流,使用getInputStream方法获取。
(5)读取内容并处理
(6)关闭连接,通过调用disconnect方法关闭当前的连接。
关键代码如下:
使用过程中不要忘记添加权限
1 <uses-permission android:name="android.permission.INTERNET"/>
• GET
1 public String get(String urlPath) { 2 HttpURLConnection connection = null; 3 InputStream is = null; 4 try { 5 URL url = new URL(urlPath); 6 //获得URL对象 7 connection = (HttpURLConnection) url.openConnection(); 8 //获得HttpURLConnection对象 9 connection.setRequestMethod("GET"); 10 // 默认为GET 11 connection.setUseCaches(false); 12 //不使用缓存 13 connection.setConnectTimeout(10000); 14 //设置超时时间 15 connection.setReadTimeout(10000); 16 //设置读取超时时间 17 connection.setDoInput(true); 18 //设置是否从httpUrlConnection读入,默认情况下是true; 19 if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { 20 //相应码是否为200 21 is = connection.getInputStream(); 22 //获得输入流 23 BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 24 //包装字节流为字符流 25 StringBuilder response = new StringBuilder(); 26 String line; 27 while ((line = reader.readLine()) != null) { 28 response.append(line); 29 } 30 return response.toString(); 31 } 32 } catch (Exception e) { 33 e.printStackTrace(); 34 } finally { 35 if (connection != null) { 36 connection.disconnect(); 37 connection = null; 38 } 39 if (is != null) { 40 try { 41 is.close(); 42 is = null; 43 } catch (IOException e) { 44 e.printStackTrace(); 45 } 46 } 47 } 48 return null; 49 }
• POST
1 private String post(String urlPath, Map<String, String> params) { 2 if (params == null || params.size() == 0) { 3 return get(urlPath); 4 } 5 OutputStream os = null; 6 InputStream is = null; 7 HttpURLConnection connection = null; 8 StringBuffer body = getParamString(params); 9 byte[] data = body.toString().getBytes(); 10 try { 11 URL url = new URL(urlPath); 12 //获得URL对象 13 connection = (HttpURLConnection) url.openConnection(); 14 //获得HttpURLConnection对象 15 connection.setRequestMethod("POST"); 16 // 设置请求方法为post 17 connection.setUseCaches(false); 18 //不使用缓存 19 connection.setConnectTimeout(10000); 20 //设置超时时间 21 connection.setReadTimeout(10000); 22 //设置读取超时时间 23 connection.setDoInput(true); 24 //设置是否从httpUrlConnection读入,默认情况下是true; 25 connection.setDoOutput(true); 26 //设置为true后才能写入参数 27 connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 28 connection.setRequestProperty("Content-Length", String.valueOf(data.length)); 29 os = connection.getOutputStream(); 30 os.write(data); 31 //写入参数 32 if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { 33 //相应码是否为200 34 is = connection.getInputStream(); 35 //获得输入流 36 BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 37 //包装字节流为字符流 38 StringBuilder response = new StringBuilder(); 39 String line; 40 while ((line = reader.readLine()) != null) { 41 response.append(line); 42 } 43 return response.toString(); 44 } 45 } catch (Exception e) { 46 e.printStackTrace(); 47 } finally { 48 //关闭 49 if (os != null) { 50 try { 51 os.close(); 52 } catch (IOException e) { 53 e.printStackTrace(); 54 } 55 } 56 if (is != null) { 57 try { 58 is.close(); 59 } catch (IOException e) { 60 e.printStackTrace(); 61 } 62 } 63 if (connection != null) { 64 connection.disconnect(); 65 connection = null; 66 } 67 } 68 return null; 69 } 70 71 private StringBuffer getParamString(Map<String, String> params) { 72 StringBuffer result = new StringBuffer(); 73 Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator(); 74 while (iterator.hasNext()) { 75 Map.Entry<String, String> param = iterator.next(); 76 String key = param.getKey(); 77 String value = param.getValue(); 78 result.append(key).append(‘=‘).append(value); 79 if (iterator.hasNext()) { 80 result.append(‘&‘); 81 } 82 } 83 return result; 84 }
二、使用HttpClient(使用类似于浏览器输入网址,浏览网页的过程)
1. HttpClient特点:
高效稳定,但是维护成本高昂,故android 开发团队不愿意在维护该库,而是转投更为轻便的HttpUrlConnection。
2. HttpClient用法:
(1)HttpClient是一个接口,因此无法直接创建它的实例,一般都是创建一个DefaultHttpClient实例.
(2)如果要发起Get请求,需要创建一个HttpGet对象,并传入请求地址
(3)如果要发起Post请求,需要创建一个HttpPost对象。并传入请求地址,通过setEntity函数设置请求参数
(4)调用execute方法,传入HttpGet或者HttpPost实例,执行后返回HttpResponse对象,判断响应状态码
(5)解析响应结果,通过调用getEntity函数获得一个HttpEntity对象,之后可以通过EntityUtils.toString方法将其转换为字符串
由于在android2.3之后就被HttpUrlConnection取代了,这里也不过多介绍了,不过当初学习它的时候还没接触到其他库,就感觉它好方便,下面简单贴出使用方法:
• GET
1 private String get(String url){ 2 HttpClient client=null; 3 HttpGet request=null; 4 try { 5 client=new DefaultHttpClient(); 6 request=new HttpGet(url); 7 HttpResponse response=client.execute(request); 8 if(response.getStatusLine().getStatusCode()== HttpStatus.SC_OK){ 9 String result=EntityUtils.toString(response.getEntity(),"UTF-8"); 10 return result; 11 } 12 } catch (IOException e) { 13 e.printStackTrace(); 14 } 15 return null; 16 }
• POST
1 private String post(String url,List<NameValuePair> params){ 2 HttpClient client=null; 3 HttpPost request=null; 4 try { 5 client=new DefaultHttpClient(); 6 request=new HttpPost(url); 7 request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); 8 HttpResponse response=client.execute(request); 9 if(response.getStatusLine().getStatusCode()== HttpStatus.SC_OK){ 10 String result=EntityUtils.toString(response.getEntity(),"UTF-8"); 11 return result; 12 } 13 } catch (IOException e) { 14 e.printStackTrace(); 15 } 16 return null; 17 }
三、使用Android Asynchronous Http Client(开源项目组件)
Android Asynchronous Http Client一看名字就知道它是基于Http Client的,但是呢在安卓中Http Client已经废弃了,所以也不建议使用这个库了。然后仍然有一些可取的内容值得学习,所以这里也介绍一下。
1. Android Asynchronous Http Client特点:
- 所以请求在子线程中完成,请求回调在调用该请求的线程中完成
- 使用线程池
- 使用RequestParams类封装请求参数
- 支持文件上传
- 持久化cookie到SharedPreferences,个人感觉这一点也是这个库的重要特点,可以很方便的完成一些模拟登录
- 支持json
- 支持HTTP Basic Auth
2. 用法:
(1)编写一个静态的HttpClient,如下:
1 public class TestClient { 2 private static final String BASE_URL = 3 "http://121.41.119.107/"; 4 5 private static AsyncHttpClient client = 6 new AsyncHttpClient(); 7 8 public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { 9 client.get(getAbsoluteUrl(url), params, responseHandler); 10 } 11 12 public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { 13 client.post(getAbsoluteUrl(url), params, responseHandler); 14 } 15 16 private static String getAbsoluteUrl(String relativeUrl) { 17 return BASE_URL + relativeUrl; 18 } 19 }
(2)调用get或者post方法,参数通过RequestParams传递,没有参数则传递null
1 RequestParams params = new RequestParams(); 2 params.put("","");
(3)如果要保存cookie,在发起请求之前,调用一下代码:
1 PersistentCookieStore myCookieStore = new PersistentCookieStore(this); 2 client.setCookieStore(myCookieStore);
之后请求所得到的cookie都会自动持久化
如果要自己添加cookie,则调用以下代码:
1 BasicClientCookie newCookie = new BasicClientCookie("cookiesare", "awesome"); 2 newCookie.setVersion(1); 3 newCookie.setDomain("mydomain.com"); 4 newCookie.setPath("/"); 5 myCookieStore.addCookie(newCookie);
(4)使用回调函数中处理返回的结果:
1 private void get(){ 2 TestClient.get("test/index.php", null, new AsyncHttpResponseHandler() { 3 @Override 4 public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { 5 6 } 7 8 @Override 9 public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { 10 11 } 12 }); 13 } 14 private void post(){ 15 RequestParams params = new RequestParams(); 16 params.put("user","asas"); 17 params.put("pass","12121"); 18 params.put("time","1212121"); 19 TestClient.post("test/login.php", params, new AsyncHttpResponseHandler() { 20 @Override 21 public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { 22 23 } 24 25 @Override 26 public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { 27 28 } 29 }); 30 }