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项目,可以对其进行简单的界面布局,如图:

安卓开发-HttpClient使用_第1张图片

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

安卓开发-HttpClient使用_第2张图片

  源码下载

总结

  最近的两次博客中,已经分别介绍了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 如何优雅地给Activity和Fragement传入参数
  2. Android中系统设置参数改变监听(以时间同步为例)
  3. 编程回忆之Android回忆(Android应用参数的获取)
  4. android 参数 加密,解密 参数提交,数据返回
  5. Android Camera中参数设置
  6. Android 数据存储(数据库、文件、参数)操作实例
  7. android客户端通过Get方式提交参数给服务器,使用URL和HttpURLConn
  8. android 读取资源字符串的 方法
  9. Android之SimpleAdapter简单实例和SimpleAdapter参数说明(zt)

随机推荐

  1. Eclipse Android(安卓)ADT 安装问题详解
  2. Android之WebView简单执行一条JS代码
  3. Android(安卓)挂载 NFS
  4. Android6.0 设置永不休眠
  5. Android(安卓)View 下拉刷新之头部效果自
  6. Android(安卓)SDK 2.2 开发环境安装
  7. android ksoap2 访问webservice,连续两次
  8. Android(安卓)滚动字幕实现
  9. [转]Android(安卓)分裂的多面性
  10. android 蓝牙搜索、配对连接通信总结