• Android进阶笔记01:Android 网络请求库的比较及实战(一)


    在实际开发中,有的时候需要频繁的网络请求,而网络请求的方式很多,最常见的也就那么几个。本篇文章对常见的网络请求库进行一个总结。

    一、使用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     }
  • 相关阅读:
    c++中的const关键字
    用类模板实现容器存储自定义数据类型(类似于STL里面的vector)
    用类模板实现容器存储普通数据类型(类似于STL里面的vector)
    pgmpy包的安装,以及conda的安装
    【SQL语言】SQL语言基础02
    【win7系统】win7系统常遇到的一些问题
    【博客收集】一些关于个人博客、程序员书单、程序资源、学习方法的博文(持续更新中~)!
    【分享】一些好的网站与技术博客
    【ORACLE】Oracle 忘记用户名和密码的和用户被锁定的解决办法
    【ORACLE】SQL Developer 与 PL/SQL Developer与SQL PLUS的使用问题
  • 原文地址:https://www.cnblogs.com/hebao0514/p/4847286.html
Copyright © 2020-2023  润新知