http://blog.csdn.net/zhangfei_jiayou/article/details/20797255

http://blog.csdn.net/zhangfei_jiayou/article/details/20797255

http://blog.csdn.net/zhangfei_jiayou/article/details/20797255

http://blog.csdn.net/zhangfei_jiayou/article/details/20797255

http://blog.csdn.net/zhangfei_jiayou/article/details/20797255



Android--Apache HttpClient

分类:androidjava 47人阅读 评论(0) 收藏 举报

HttpClient是Apache开源组织提供的一个开源的项目,从名字上就可以看出,它是一个简单的HTTP客户端(并不是浏览器),可以发送HTTP请求,接受HTTP响应。但是不会缓存服务器的响应,不能执行HTTP页面中签入嵌入的JS代码,自然也不会对页面内容进行任何解析、处理,这些都是需要开发人员来完成的。

  现在Android已经成功集成了HttpClient,所以开发人员在Android项目中可以直接使用HttpClient来想Web站点提交请求以及接受响应,如果使用其他的Java项目,需要引入进相应的Jar包。HttpClient可以在官网上下载。

  

HttpClient

  HttpClient其实是一个interface类型,HttpClient封装了对象需要执行的Http请求、身份验证、连接管理和其它特性。从文档上看,HttpClient有三个已知的实现类分别是:AbstractHttpClient,AndroidHttpClient,DefaultHttpClient,会发现有一个专门为Android应用准备的实现类AndroidHttpClient,当然使用常规的DefaultHttpClient也可以实现功能,但是既然开发的是Android应用程序,还是使用Android专有的实现类,一定有其优势。

  从两个类包所有在位置就可以看出区别,AndroidHttpClient定义在android.net.http.AndroidHttpClient包下,属于Android原生的http访问,而DefaultHttpClient定义在org.apache.http.impl.client.DefaultHttpClient包下,属于对apche项目的支持。而AndroidHttpClient没有公开的构造函数,只能通过静态方法newInstance()方法来获得AndroidHttpClient对象。

  AndroidHttpClient对于DefaultHttpClient做了一些改进,使其更使用用于Android项目:

  1. 关掉过期检查,自连接可以打破所有的时间限制。
  2. 可以设置ConnectionTimeOut(连接超时)和SoTimeout(读取数据超时)。
  3. 关掉重定向。
  4. 使用一个Session缓冲用于SSL Sockets。
  5. 如果服务器支持,使用gzip压缩方式用于在服务端和客户端传递的数据。
  6. 默认情况下不保留Cookie。    

  简单来说,用HttpClient发送请求、接收响应都很简单,只需要几个步骤即可:

  1. 创建HttpClient对象。
  2. 创建对应的发送请求的对象,如果需要发送GET请求,则创建HttpGet对象,如果需要发送POST请求,则创建HttpPost对象。
  3. 对于发送请求的参数,GET和POST使用的方式不同,GET方式可以使用拼接字符串的方式,把参数拼接在URL结尾;POST方式需要使用setEntity(HttpEntity entity)方法来设置请求参数。
  4. 调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法返回一个HttpResponse对象。
  5. 调用HttpResponse的对应方法获取服务器的响应头、响应内容等。

DefaultHttpClient

  先看看使用DefaultHttpClient方式发送Web站点请求,上面已经简要说明了步骤,在这里简要说明一个参数的传递问题,对于GET方式,只需要拼接字符串就在URL结尾即可,但是对于POST方式,需要传递HttpEntity对象,HttpEntity为一个接口,有多个实现类,可以使用其间接子继承,UrlEncodedFormEntity类来保存请求参数,并传递给HttpPost。

  此例子简单实现了在Android客户端使用DefaultHttpClient实现一个Http站点登陆的实现,使用的是POST传递,其传递值只需要传递username+password即可,当传递的数据为admin+123则认为登陆成功。Web站点使用.net的架构,一个一般处理程序,简单的比对账户密码,这里就不在此讲解。

  因为Android4.0之后对使用网络有特殊要求,已经无法再在主线程中访问网络了,必须使用多线程访问的模式,其他的一些信息在代码注释中已经说明。

DefaultHttpClient-Code

 1 package com.bgxt.httpUtils;  2  3 import java.io.ByteArrayOutputStream;  4 import java.io.IOException;  5 import java.io.InputStream;  6 import java.io.UnsupportedEncodingException;  7 import java.util.ArrayList;  8 import java.util.HashMap;  9 import java.util.List;  10 import java.util.Map;  11  12 import org.apache.http.HttpResponse;  13 import org.apache.http.NameValuePair;  14 import org.apache.http.client.ClientProtocolException;  15 import org.apache.http.client.entity.UrlEncodedFormEntity;  16 import org.apache.http.client.methods.HttpPost;  17 import org.apache.http.impl.client.DefaultHttpClient;  18 import org.apache.http.message.BasicNameValuePair;  19  20 public class httpClientUtils implements Runnable {  21     /** 22  * 对于Android4.0之上的环境下,不能在主线程中访问网络 所以这里另新建了一个实现了Runnable接口的Http访问类  23      */ 24     private String username;  25     private String password;  26  27     public httpClientUtils(String username, String password) {  28         // 初始化用户名和密码 29         this.username = username;  30         this.password = password;  31  }  32  33  @Override  34     public void run() {  35         // 设置访问的Web站点 36         String path = "http://192.168.1.103:1231/loginas.ashx";  37         // 设置Http请求参数 38         Map<String, String> params = new HashMap<String, String>();  39         params.put("username", username);  40         params.put("password", password);  41  42         String result = sendHttpClientPost(path, params, "utf-8");  43         // 把返回的接口输出 44  System.out.println(result);  45  }  46  47     /** 48  * 发送Http请求到Web站点  49  *  50  * @param path  51  * Web站点请求地址  52  * @param map  53  * Http请求参数  54  * @param encode  55  * 编码格式  56  * @return Web站点响应的字符串  57      */ 58     private String sendHttpClientPost(String path, Map<String, String> map,  59  String encode) {  60         List<NameValuePair> list = new ArrayList<NameValuePair>();  61         if (map != null && !map.isEmpty()) {  62             for (Map.Entry<String, String> entry : map.entrySet()) {  63                 // 解析Map传递的参数,使用一个键值对对象BasicNameValuePair保存。 64                 list.add(new BasicNameValuePair(entry.getKey(), entry  65  .getValue()));  66  }  67  }  68         try {  69             // 实现将请求 的参数封装封装到HttpEntity中。 70             UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, encode);  71             // 使用HttpPost请求方式 72             HttpPost httpPost = new HttpPost(path);  73             // 设置请求参数到Form中。 74  httpPost.setEntity(entity);  75             // 实例化一个默认的Http客户端 76             DefaultHttpClient client = new DefaultHttpClient();  77             // 执行请求,并获得响应数据 78             HttpResponse httpResponse = client.execute(httpPost);  79             // 判断是否请求成功,为200时表示成功,其他均问有问题。 80             if (httpResponse.getStatusLine().getStatusCode() == 200) {  81                 // 通过HttpEntity获得响应流 82                 InputStream inputStream = httpResponse.getEntity().getContent();  83                 return changeInputStream(inputStream, encode);  84  }  85         } catch (UnsupportedEncodingException e) {  86  e.printStackTrace();  87         } catch (ClientProtocolException e) {  88  e.printStackTrace();  89         } catch (IOException e) {  90  e.printStackTrace();  91  }  92         return "";  93  }  94  95     /** 96  * 把Web站点返回的响应流转换为字符串格式  97  *  98  * @param inputStream  99  * 响应流 100  * @param encode 101  * 编码格式 102  * @return 转换后的字符串 103      */104     private String changeInputStream(InputStream inputStream, String encode) { 105         ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 106         byte[] data = new byte[1024]; 107         int len = 0; 108         String result = ""; 109         if (inputStream != null) { 110             try { 111                 while ((len = inputStream.read(data)) != -1) { 112                     outputStream.write(data, 0, len); 113  } 114                 result = new String(outputStream.toByteArray(), encode); 115 116             } catch (IOException e) { 117  e.printStackTrace(); 118  } 119  } 120         return result; 121  } 122 123 }

AndroidHttpClient

  使用AndroidHttpClient的方式和DefaultHttpClient差不多,不多的几点区别上面已经说明,但是在此例子中没有体现。有一点需要注意的是,AndroidHttpClient是一个final类,也没有公开的构造函数,所以无法使用new的形式对其进行实例化,必须使用AndroidHttpClient.newInstance()方法获得AndroidHttpClient对象。

  示例中依然是使用POST请求,实现的功能和DefaultHttpClient示例一样。细节部分已经在注释中体现,直接看代码即可。

 1 package com.bgxt.httpUtils;  2  3 import java.io.ByteArrayOutputStream;  4 import java.io.IOException;  5 import java.io.InputStream;  6 import java.io.UnsupportedEncodingException;  7 import java.util.ArrayList;  8 import java.util.HashMap;  9 import java.util.List;  10 import java.util.Map;  11  12 import org.apache.http.HttpResponse;  13 import org.apache.http.NameValuePair;  14 import org.apache.http.client.ClientProtocolException;  15 import org.apache.http.client.HttpClient;  16 import org.apache.http.client.entity.UrlEncodedFormEntity;  17 import org.apache.http.client.methods.HttpPost;  18 import org.apache.http.impl.client.DefaultHttpClient;  19 import org.apache.http.message.BasicNameValuePair;  20  21 import android.net.http.AndroidHttpClient;  22  23 public class AndroidHttpClientUtils implements Runnable {  24  25     private String username;  26     private String password;  27  28     public AndroidHttpClientUtils(String username, String password) {  29         // 初始化用户名和密码 30         this.username = username;  31         this.password = password;  32  }  33  34  @Override  35     public void run() {  36         // 设置访问的Web站点 37         String path = "http://192.168.1.103:1231/loginas.ashx";  38         //设置Http请求参数 39         Map<String, String> params = new HashMap<String, String>();  40         params.put("username", username);  41         params.put("password", password);  42  43         String result = sendHttpClientPost(path, params, "utf-8");  44         //把返回的接口输出 45  System.out.println(result);  46  }  47     /** 48  * 发送Http请求到Web站点  49  * @param path Web站点请求地址  50  * @param map Http请求参数  51  * @param encode 编码格式  52  * @return Web站点响应的字符串  53      */ 54     private String sendHttpClientPost(String path,Map<String, String> map,String encode)  55  {  56         List<NameValuePair> list=new ArrayList<NameValuePair>();  57         if(map!=null&&!map.isEmpty())  58  {  59             for(Map.Entry<String, String> entry:map.entrySet())  60  {  61                 //解析Map传递的参数,使用一个键值对对象BasicNameValuePair保存。 62                 list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));  63  }  64  }  65         try {  66             //实现将请求 的参数封装封装到HttpEntity中。 67             UrlEncodedFormEntity entity=new UrlEncodedFormEntity(list, encode);  68             //使用HttpPost请求方式 69             HttpPost httpPost=new HttpPost(path);  70             //设置请求参数到Form中。 71  httpPost.setEntity(entity);  72             //实例化一个默认的Http客户端,使用的是AndroidHttpClient 73             HttpClient client=AndroidHttpClient.newInstance("");  74             //执行请求,并获得响应数据 75             HttpResponse httpResponse= client.execute(httpPost);  76             //判断是否请求成功,为200时表示成功,其他均问有问题。 77             if(httpResponse.getStatusLine().getStatusCode()==200)  78  {  79                 //通过HttpEntity获得响应流 80                 InputStream inputStream=httpResponse.getEntity().getContent();  81                 return changeInputStream(inputStream,encode);  82  }  83              84         } catch (UnsupportedEncodingException e) {  85             // TODO Auto-generated catch block 86  e.printStackTrace();  87         } catch (ClientProtocolException e) {  88             // TODO Auto-generated catch block 89  e.printStackTrace();  90         } catch (IOException e) {  91             // TODO Auto-generated catch block 92  e.printStackTrace();  93  }  94          95         return "";  96  }  97     /** 98  * 把Web站点返回的响应流转换为字符串格式  99  * @param inputStream 响应流 100  * @param encode 编码格式 101  * @return 转换后的字符串 102      */103     private String changeInputStream(InputStream inputStream, 104  String encode) { 105         ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 106         byte[] data = new byte[1024]; 107         int len = 0; 108         String result=""; 109         if (inputStream != null) { 110             try { 111                 while ((len = inputStream.read(data)) != -1) { 112                     outputStream.write(data,0,len); 113  } 114                 result=new String(outputStream.toByteArray(),encode); 115                 116             } catch (IOException e) { 117  e.printStackTrace(); 118  } 119  } 120         return result; 121  } 122 }

  在本文的示例中,环境是使用的Android项目,可以对其进行简单的界面布局,如图:

  如果输入用户和密码为:admin+123,则可以再LogCat中查看到登录成功。

  源码下载

总结

  最近的两次博客中,已经分别介绍了HttpUrlConnection和HttpClient两种方式,通过Http协议对Web站点的访问。如果还不了解HttpURLConnection的读者,可以看看Android--Http协议。

  根据官方文档上说的显示,Android包括两个Http客户端:HttpURLConnection和Apache HttpClient。并且都支持HTTPS,流媒体上传下载,并且可配置超时以及支持IPv6和连接池技术。但是因为移动设备的局限性,HttpURLConnection会是比Apache Http更好的选择,因为其API简单,运行消耗内存小,并且具有公开化的压缩算法,以及响应缓存,能更好的减少网络使用,提供运行速度和节省电池。

  但是也不能否认Apache HttpClient,它有大量的灵活的API,实现比较稳定,少有Bug,可造成的问题就是很难在不影响其兼容性的情况下对其进行改进了。现在Android开发者已经慢慢放弃Apache HttpClient的使用,转而使用HttpURLConnection。但是对于Android2.2之前的版本,HttpURLConnection具有一个致命的BUG,在响应输入流InputStream中调用.Close()方法将会阻碍连接池,因为这个BUG,只能放弃连接池的使用,但是Apache HttpClient不存在这个问题,当然Android2.3之后的版本中,HttpURLConnection已经解决了这个BUG,可以放心使用。

转载至:http://www.cnblogs.com/plokmju/p/Android_apacheHttpClient.html

























http://blog.csdn.net/zhangfei_jiayou/article/details/8076215

http://blog.csdn.net/zhangfei_jiayou/article/details/8076215

http://blog.csdn.net/zhangfei_jiayou/article/details/8076215



基于Apache的HttpClient进行HTTP网络访问

分类:javaandroid 815人阅读 评论(0) 收藏 举报 在Android中,除了使用java.net包下的API访问HTTP服务之外,我们还可以换一种途径去完成工作.Android SDK附带了Apache的HttpClient API.Apache HttpClient是一个完善的HTTP客户端,它提供了对HTTP协议的全面支持,可以使用HTTP GET和POST进行访问.下面我们就结合实例,介绍一下HttpClient的使用方法:
[html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <manifestxmlns:android="http://schemas.android.com/apk/res/android"
  3. package=""
  4. android:versionCode="1"
  5. android:versionName="1.0">
  6. <applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
  7. <!--配置测试要使用的类库-->
  8. <uses-libraryandroid:name="android.test.runner"/>
  9. </application>
  10. <!--配置测试设备的主类和目标包-->
  11. <instrumentationandroid:name="android.test.InstrumentationTestRunner"
  12. android:targetPackage="com.scott.http"/>
  13. <!--访问HTTP服务所需的网络权限-->
  14. <uses-permissionandroid:name="android.permission.INTERNET"/>
  15. <uses-sdkandroid:minSdkVersion="8"/>
  16. </manifest>

然后,我们的单元测试类需要继承android.test.AndroidTestCase类,这个类本身是继承junit.framework.TestCase,并提供了getContext()方法,用于获取Android上下文环境,这个设计非常有用,因为很多Android API都是需要Context才能完成的.

现在让我们来看一下我们的测试用例,HttpTest.java代码如下:

[java] view plain copy
  1. publicclassHttpTestextendsAndroidTestCase{
  2. privatestaticfinalStringPATH="http://192.168.1.57:8080/web";
  3. publicvoidtestGet()throwsException{
  4. HttpClientclient=newDefaultHttpClient();
  5. HttpGetget=newHttpGet(PATH
  6. +"/TestServlet?id=1001&name=john&age=60");
  7. HttpResponseresponse=client.execute(get);
  8. if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
  9. InputStreamis=response.getEntity().getContent();
  10. Stringresult=inStream2String(is);
  11. Assert.assertEquals(result,"GET_SUCCESS");
  12. }
  13. }
  14. publicvoidtestPost()throwsException{
  15. HttpClientclient=newDefaultHttpClient();
  16. HttpPostpost=newHttpPost(PATH+"/TestServlet");
  17. List<NameValuePair>params=newArrayList<NameValuePair>();
  18. params.add(newBasicNameValuePair("id","1001"));
  19. params.add(newBasicNameValuePair("name","john"));
  20. params.add(newBasicNameValuePair("age","60"));
  21. HttpEntityformEntity=newUrlEncodedFormEntity(params);
  22. post.setEntity(formEntity);
  23. HttpResponseresponse=client.execute(post);
  24. if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
  25. InputStreamis=response.getEntity().getContent();
  26. Stringresult=inStream2String(is);
  27. Assert.assertEquals(result,"POST_SUCCESS");
  28. }
  29. }
  30. publicvoidtestUpload()throwsException{
  31. InputStreamis=getContext().getAssets().open("books.xml");
  32. HttpClientclient=newDefaultHttpClient();
  33. HttpPostpost=newHttpPost(PATH+"/UploadServlet");
  34. InputStreamBodyisb=newInputStreamBody(is,"books.xml");
  35. MultipartEntitymultipartEntity=newMultipartEntity();
  36. multipartEntity.addPart("file",isb);
  37. multipartEntity.addPart("desc",newStringBody("thisisdescription."));
  38. post.setEntity(multipartEntity);
  39. HttpResponseresponse=client.execute(post);
  40. if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
  41. is=response.getEntity().getContent();
  42. Stringresult=inStream2String(is);
  43. Assert.assertEquals(result,"UPLOAD_SUCCESS");
  44. }
  45. }
  46. //将输入流转换成字符串
  47. privateStringinStream2String(InputStreamis)throwsException{
  48. ByteArrayOutputStreambaos=newByteArrayOutputStream();
  49. byte[]buf=newbyte[1024];
  50. intlen=-1;
  51. while((len=is.read(buf))!=-1){
  52. baos.write(buf,0,len);
  53. }
  54. returnnewString(baos.toByteArray());
  55. }
  56. }
因为此文件包含三个测试用例,所以我将会逐个介绍一下.
首先,需要注意的是,我们定位服务器地址时使用到了IP,因为这里不能用localhost,服务端是在windows上运行,而本单元测试运行在Android平台,如果使用localhost就意味着在Android内部去访问服务,可能是访问不到的,所以必须用IP来定位服务.
我们先来分析一下testGet测试用例.我们使用了HttpGet,请求参数直接附在URL后面,然后由HttpClient执行GET请求,如果响应成功的话,取得响应内如输入流,并转换成字符串,最后判断是否为GET_SUCCESS.
testGet测试对应服务端Servlet代码如下:

[java] view plain copy
  1. @Override
  2. protectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
  3. System.out.println("doGetmethodiscalled.");
  4. Stringid=request.getParameter("id");
  5. Stringname=request.getParameter("name");
  6. Stringage=request.getParameter("age");
  7. System.out.println("id:"+id+",name:"+name+",age:"+age);
  8. response.getWriter().write("GET_SUCCESS");
  9. }
然后再说testPost测试用例。我们使用了HttpPost,URL后面并没有附带参数信息,参数信息被包装成一个由NameValuePair类型组成的集合的形式,然后经过UrlEncodedFormEntity处理后调用HttpPost的setEntity方法进行参数设置,最后由HttpClient执行。
testPost测试对应的服务端代码如下:

[java] view plain copy
  1. @Override
  2. protectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
  3. System.out.println("doPostmethodiscalled.");
  4. Stringid=request.getParameter("id");
  5. Stringname=request.getParameter("name");
  6. Stringage=request.getParameter("age");
  7. System.out.println("id:"+id+",name:"+name+",age:"+age);
  8. response.getWriter().write("POST_SUCCESS");
  9. }
上面两个是最基本的GET请求和POST请求,参数都是文本数据类型,能满足普通的需求,不过在有的场合例如我们要用到上传文件的时候,就不能使用基本的GET请求和POST请求了,我们要使用多部件的POST请求。下面介绍一下如何使用多部件POST操作上传一个文件到服务端。
由于Android附带的HttpClient版本暂不支持多部件POST请求,所以我们需要用到一个HttpMime开源项目,该组件是专门处理与MIME类型有关的操作。因为HttpMime是包含在HttpComponents 项目中的,所以我们需要去apache官方网站下载HttpComponents,然后把其中的HttpMime.jar包放到项目中去。
然后,我们观察testUpload测试用例,我们用HttpMime提供的InputStreamBody处理文件流参数,用StringBody处理普通文本参数,最后把所有类型参数都加入到一个MultipartEntity的实例中,并将这个multipartEntity设置为此次POST请求的参数实体,然后执行POST请求。服务端Servlet代码如下:

[java] view plain copy
  1. @SuppressWarnings("serial")
  2. publicclassUploadServletextendsHttpServlet{
  3. @Override
  4. @SuppressWarnings("rawtypes")
  5. protectedvoiddoPost(HttpServletRequestrequest,
  6. HttpServletResponseresponse)throwsServletException,IOException{
  7. booleanisMultipart=ServletFileUpload.isMultipartContent(request);
  8. if(isMultipart){
  9. FileItemFactoryfactory=newDiskFileItemFactory();
  10. ServletFileUploadupload=newServletFileUpload(factory);
  11. try{
  12. Listitems=upload.parseRequest(request);
  13. Iteratoriter=items.iterator();
  14. while(iter.hasNext()){
  15. FileItemitem=(FileItem)iter.next();
  16. if(item.isFormField()){
  17. //普通文本信息处理
  18. StringparamName=item.getFieldName();
  19. StringparamValue=item.getString();
  20. System.out.println(paramName+":"+paramValue);
  21. }else{
  22. //上传文件信息处理
  23. StringfileName=item.getName();
  24. byte[]data=item.get();
  25. StringfilePath=getServletContext().getRealPath(
  26. "/files")
  27. +"/"+fileName;
  28. FileOutputStreamfos=newFileOutputStream(filePath);
  29. fos.write(data);
  30. fos.close();
  31. }
  32. }
  33. }catch(FileUploadExceptione){
  34. e.printStackTrace();
  35. }
  36. }
  37. response.getWriter().write("UPLOAD_SUCCESS");
  38. }
  39. }
服务端使用apache开源项目FileUpload进行处理,所以我们需要commons-fileupload和commons-io这两个项目的jar包。
介绍完上面的三种不同的情况之后,我们需要考虑一个问题,在实际应用中,我们不能每次都新建HttpClient,而是应该只为整个应用创建一个HttpClient,并将其用于所有HTTP通信.此外,还应该注意在通过一个HttpClient同时发出多个请求时可能发生的多线程问题.针对这两个问题,我们需要改进一下我们的项目:
1.扩展系统默认的Application,并应用在项目中。
2.使用HttpClient类库提供的ThreadSafeClientManager来创建和管理HttpClient。
其中MyApplication扩展了系统的Application,代码如下:

[java] view plain copy
  1. publicclassMyApplicationextendsApplication{
  2. privateHttpClienthttpClient;
  3. @Override
  4. publicvoidonCreate(){
  5. super.onCreate();
  6. httpClient=this.createHttpClient();
  7. }
  8. @Override
  9. publicvoidonLowMemory(){
  10. super.onLowMemory();
  11. this.shutdownHttpClient();
  12. }
  13. @Override
  14. publicvoidonTerminate(){
  15. super.onTerminate();
  16. this.shutdownHttpClient();
  17. }
  18. //创建HttpClient实例
  19. privateHttpClientcreateHttpClient(){
  20. HttpParamsparams=newBasicHttpParams();
  21. HttpProtocolParams.setVersion(params,HttpVersion.HTTP_1_1);
  22. HttpProtocolParams.setContentCharset(params,
  23. HTTP.DEFAULT_CONTENT_CHARSET);
  24. HttpProtocolParams.setUseExpectContinue(params,true);
  25. SchemeRegistryschReg=newSchemeRegistry();
  26. schReg.register(newScheme("http",PlainSocketFactory
  27. .getSocketFactory(),80));
  28. schReg.register(newScheme("https",
  29. SSLSocketFactory.getSocketFactory(),443));
  30. ClientConnectionManagerconnMgr=newThreadSafeClientConnManager(
  31. params,schReg);
  32. returnnewDefaultHttpClient(connMgr,params);
  33. }
  34. //关闭连接管理器并释放资源
  35. privatevoidshutdownHttpClient(){
  36. if(httpClient!=null&&httpClient.getConnectionManager()!=null){
  37. httpClient.getConnectionManager().shutdown();
  38. }
  39. }
  40. //对外提供HttpClient实例
  41. publicHttpClientgetHttpClient(){
  42. returnhttpClient;
  43. }
  44. }
我们重写了onCreate()方法,在系统启动时就创建一个HttpClient;重写了onLowMemory()和onTerminate()方法,在内存不足和应用结束时关闭连接,释放资源.需要注意的是,当实例化DefaultHttpClient时,传入一个由ThreadSafeClientConnManager创建的一个ClientConnectionManager实例,负责管理HttpClient的HTTP连接.

然后,想要让我们这个加强版的“Application”生效,需要在AndroidManifest.xml中做如下配置:

[html] view plain copy
  1. <applicationandroid:name=".MyApplication"...>
  2. ....
  3. </application>
如果我们没有配置,系统默认会使用android.app.Application,我们添加了配置,系统就会使用我们的com.scott.http.MyApplication,然后就可以在context中调用getApplication()来获取MyApplication实例.
有了上面的配置,我们就可以在活动中应用了,HttpActivity.java代码如下:

[java] view plain copy
  1. publicclassHttpActivityextendsActivity{
  2. @Override
  3. protectedvoidonCreate(BundlesavedInstanceState){
  4. super.onCreate(savedInstanceState);
  5. setContentView(R.layout.main);
  6. Buttonbtn=(Button)findViewById(R.id.btn);
  7. btn.setOnClickListener(newView.OnClickListener(){
  8. @Override
  9. publicvoidonClick(Viewv){
  10. execute();
  11. }
  12. });
  13. }
  14. privatevoidexecute(){
  15. try{
  16. MyApplicationapp=(MyApplication)this.getApplication();//获取MyApplication实例
  17. HttpClientclient=app.getHttpClient();//获取HttpClient实例
  18. HttpGetget=newHttpGet(
  19. "http://192.168.1.57:8080/web/TestServlet?id=1001&name=john&age=60");
  20. HttpResponseresponse=client.execute(get);
  21. if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
  22. InputStreamis=response.getEntity().getContent();
  23. Stringresult=inStream2String(is);
  24. Toast.makeText(this,result,Toast.LENGTH_LONG).show();
  25. }
  26. }catch(Exceptione){
  27. e.printStackTrace();
  28. }
  29. }
  30. //将输入流转换成字符串
  31. privateStringinStream2String(InputStreamis)throwsException{
  32. ByteArrayOutputStreambaos=newByteArrayOutputStream();
  33. byte[]buf=newbyte[1024];
  34. intlen=-1;
  35. while((len=is.read(buf))!=-1){
  36. baos.write(buf,0,len);
  37. }
  38. returnnewString(baos.toByteArray());
  39. }
  40. }




更多相关文章

  1. Android(安卓)Studio在引用项目时使用JDK1.8的解决办法
  2. android 如何优雅地给Activity和Fragement传入参数
  3. API 23 找不到 org.apache.http.HttpResponse;
  4. mybatisplus的坑 insert标签insert into select无参数问题的解决
  5. 箭头函数的基础使用
  6. NPM 和webpack 的基础使用
  7. Python技巧匿名函数、回调函数和高阶函数
  8. Python list sort方法的具体使用
  9. 【阿里云镜像】使用阿里巴巴DNS镜像源——DNS配置教程

随机推荐

  1. android 制作OTA 更新包
  2. android sdcard存储方案(基于fuse文件系统
  3. android交叉编译c程序
  4. android 与 服务器通信
  5. 7.1.2 DatePicker结合案例详解
  6. android 验证手机号和邮箱格式
  7. Android应用程序获取ROOT权限代码
  8. Android 6.0 Math代替FloatMath
  9. android2.3中支持的语言对照
  10. android 横竖屏切换与数据保存