3. Android框架和工具之 xUtils(HttpUtils)

1. HttpUtils 作用:

  • 支持同步,异步方式的请求;
  • 支持大文件上传,上传大文件不会oom;
  • 支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD请求;
  • 下载支持301/302重定向,支持设置是否根据Content-Disposition重命名下载的文件;
  • 返回文本内容的GET请求支持缓存,可设置默认过期时间和针对当前请求的过期时间。

 

2. HttpUtils全面注释:

  1 /*
  2 
  3 
  4 /**
  5  * 网络请求工具类
  6  * @author 阿福
  7  *
  8  */
  9 public class HttpUtils {
 10 
 11     public final static HttpCache sHttpCache = new HttpCache();
 12 
 13     private final DefaultHttpClient httpClient;
 14     private final HttpContext httpContext = new BasicHttpContext();
 15 
 16     private HttpRedirectHandler httpRedirectHandler;
 17 
 18     /**
 19      * 构造方法,默认联网15秒超时
 20      */
 21     public HttpUtils() {
 22         this(HttpUtils.DEFAULT_CONN_TIMEOUT, null);
 23     }
 24 
 25     /**
 26      * 构造方法设置超时时间
 27      * @param connTimeout 超时时间毫秒
 28      */
 29     public HttpUtils(int connTimeout) {
 30         this(connTimeout, null);
 31     }
 32 
 33     /**
 34      * 构造方法,浏览器的信息包
 35      * @param userAgent
 36      */
 37     public HttpUtils(String userAgent) {
 38         this(HttpUtils.DEFAULT_CONN_TIMEOUT, userAgent);
 39     }
 40 
 41     /**
 42      * 构造方法
 43      * @param connTimeout 链接超时时间,毫秒单位
 44      * @param userAgent  浏览器的信息包
 45      */
 46     public HttpUtils(int connTimeout, String userAgent) {
 47         HttpParams params = new BasicHttpParams();
 48 
 49         ConnManagerParams.setTimeout(params, connTimeout);
 50         HttpConnectionParams.setSoTimeout(params, connTimeout);
 51         HttpConnectionParams.setConnectionTimeout(params, connTimeout);
 52 
 53         if (TextUtils.isEmpty(userAgent)) {
 54             userAgent = OtherUtils.getUserAgent(null);
 55         }
 56         HttpProtocolParams.setUserAgent(params, userAgent);
 57 
 58         ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRouteBean(10));
 59         ConnManagerParams.setMaxTotalConnections(params, 10);
 60 
 61         HttpConnectionParams.setTcpNoDelay(params, true);
 62         HttpConnectionParams.setSocketBufferSize(params, 1024 * 8);
 63         HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
 64 
 65         SchemeRegistry schemeRegistry = new SchemeRegistry();
 66         schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
 67         schemeRegistry.register(new Scheme("https", DefaultSSLSocketFactory.getSocketFactory(), 443));
 68 
 69         httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager(params, schemeRegistry), params);
 70 
 71         httpClient.setHttpRequestRetryHandler(new RetryHandler(DEFAULT_RETRY_TIMES));
 72 
 73         httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
 74             @Override
 75             public void process(org.apache.http.HttpRequest httpRequest, HttpContext httpContext) throws org.apache.http.HttpException, IOException {
 76                 if (!httpRequest.containsHeader(HEADER_ACCEPT_ENCODING)) {
 77                     httpRequest.addHeader(HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
 78                 }
 79             }
 80         });
 81 
 82         httpClient.addResponseInterceptor(new HttpResponseInterceptor() {
 83             @Override
 84             public void process(HttpResponse response, HttpContext httpContext) throws org.apache.http.HttpException, IOException {
 85                 final HttpEntity entity = response.getEntity();
 86                 if (entity == null) {
 87                     return;
 88                 }
 89                 final Header encoding = entity.getContentEncoding();
 90                 if (encoding != null) {
 91                     for (HeaderElement element : encoding.getElements()) {
 92                         if (element.getName().equalsIgnoreCase("gzip")) {
 93                             response.setEntity(new GZipDecompressingEntity(response.getEntity()));
 94                             return;
 95                         }
 96                     }
 97                 }
 98             }
 99         });
100     }
101 
102     // ************************************    default settings & fields ****************************
103 
104     
105     private String responseTextCharset = HTTP.UTF_8;
106 
107     private long currentRequestExpiry = HttpCache.getDefaultExpiryTime();
108 
109     private final static int DEFAULT_CONN_TIMEOUT = 1000 * 15; // 15s
110 
111     private final static int DEFAULT_RETRY_TIMES = 3;
112 
113     private static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
114     private static final String ENCODING_GZIP = "gzip";
115 
116     private final static int DEFAULT_POOL_SIZE = 3;
117     private final static PriorityExecutor EXECUTOR = new PriorityExecutor(DEFAULT_POOL_SIZE);
118 
119     public HttpClient getHttpClient() {
120         return this.httpClient;
121     }
122 
123     // ***************************************** config *******************************************
124 
125     /**
126      * 配置请求文本编码,默认UTF-8
127      * @param charSet
128      * @return
129      */
130     public HttpUtils configResponseTextCharset(String charSet) {
131         if (!TextUtils.isEmpty(charSet)) {
132             this.responseTextCharset = charSet;
133         }
134         return this;
135     }
136 
137     /**
138      * http重定向处理
139      * @param httpRedirectHandler
140      * @return
141      */
142     public HttpUtils configHttpRedirectHandler(HttpRedirectHandler httpRedirectHandler) {
143         this.httpRedirectHandler = httpRedirectHandler;
144         return this;
145     }
146 
147     /**
148      * 配置http缓存大小
149      * @param httpCacheSize
150      * @return
151      */
152     public HttpUtils configHttpCacheSize(int httpCacheSize) {
153         sHttpCache.setCacheSize(httpCacheSize);
154         return this;
155     }
156 
157     /**
158      * 配置默认http缓存失效 ,默认是60秒
159      * @param defaultExpiry 
160      * @return
161      */
162     public HttpUtils configDefaultHttpCacheExpiry(long defaultExpiry) {
163         HttpCache.setDefaultExpiryTime(defaultExpiry);
164         currentRequestExpiry = HttpCache.getDefaultExpiryTime();
165         return this;
166     }
167 
168     /**
169      * 配置当前http缓存失效,时间默认60秒
170      * @param currRequestExpiry
171      * @return
172      */
173     public HttpUtils configCurrentHttpCacheExpiry(long currRequestExpiry) {
174         this.currentRequestExpiry = currRequestExpiry;
175         return this;
176     }
177 
178     /**
179      * cookie存储配置
180      * @param cookieStore
181      * @return
182      */
183     public HttpUtils configCookieStore(CookieStore cookieStore) {
184         httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
185         return this;
186     }
187 
188     /**
189      * 配置浏览器信息包
190      * @param userAgent
191      * @return
192      */
193     public HttpUtils configUserAgent(String userAgent) {
194         HttpProtocolParams.setUserAgent(this.httpClient.getParams(), userAgent);
195         return this;
196     }
197 
198     /**
199      * 配置时间链接超时
200      * @param timeout
201      * @return
202      */
203     public HttpUtils configTimeout(int timeout) {
204         final HttpParams httpParams = this.httpClient.getParams();
205         ConnManagerParams.setTimeout(httpParams, timeout);
206         HttpConnectionParams.setConnectionTimeout(httpParams, timeout);
207         return this;
208     }
209 
210     /**
211      * 配置socket时间连接溢出
212      * @param timeout
213      * @return
214      */
215     public HttpUtils configSoTimeout(int timeout) {
216         final HttpParams httpParams = this.httpClient.getParams();
217         HttpConnectionParams.setSoTimeout(httpParams, timeout);
218         return this;
219     }
220 
221     /**
222      * 配置注册Scheme
223      * @param scheme
224      * @return
225      */
226     public HttpUtils configRegisterScheme(Scheme scheme) {
227         this.httpClient.getConnectionManager().getSchemeRegistry().register(scheme);
228         return this;
229     }
230 
231     /**
232      * 配置SSLSocketFactory
233      * @param sslSocketFactory
234      * @return
235      */
236     public HttpUtils configSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
237         Scheme scheme = new Scheme("https", sslSocketFactory, 443);
238         this.httpClient.getConnectionManager().getSchemeRegistry().register(scheme);
239         return this;
240     }
241 
242     /**
243      * 配置请求重试次数
244      * @param count 重试次数
245      * @return
246      */
247     public HttpUtils configRequestRetryCount(int count) {
248         this.httpClient.setHttpRequestRetryHandler(new RetryHandler(count));
249         return this;
250     }
251 
252     /**
253      * 配置请求线程池个数
254      * @param threadPoolSize 线程池个数
255      * @return
256      */
257     public HttpUtils configRequestThreadPoolSize(int threadPoolSize) {
258         HttpUtils.EXECUTOR.setPoolSize(threadPoolSize);
259         return this;
260     }
261 
262     // ***************************************** send request 发送请求*******************************************
263 
264     /**
265      * 发送异步网络请求 -重要
266      * @param method get或者post请求等等
267      * @param url 网络请求路径
268      * @param callBack 回调
269      * @return
270      */
271     public <T> HttpHandler<T> send(HttpRequest.HttpMethod method, String url,
272                                    RequestCallBack<T> callBack) {
273         return send(method, url, null, callBack);
274     }
275 
276     /**
277      * 发送异步网络请求 -重要
278      * @param method get或者post请求等等
279      * @param url 网络请求路径
280      * @param params 请求参数
281      * @param callBack 回调
282      * @return
283      */
284     public <T> HttpHandler<T> send(HttpRequest.HttpMethod method, String url, RequestParams params,
285                                    RequestCallBack<T> callBack) {
286         if (url == null) throw new IllegalArgumentException("url may not be null");
287 
288         HttpRequest request = new HttpRequest(method, url);
289         return sendRequest(request, params, callBack);
290     }
291 
292     /**
293      * 发送同步网络请求 -用得不多
294      * @param method get或者post等方法
295      * @param url 联网网络url
296      * @return
297      * @throws HttpException
298      */
299     public ResponseStream sendSync(HttpRequest.HttpMethod method, String url) throws HttpException {
300         return sendSync(method, url, null);
301     }
302 
303     /**
304      * 发送同步网络请求 -用得不多
305      * @param method get或者post等方法
306      * @param url 联网网络url 
307      * @param params 请求参数
308      * @return
309      * @throws HttpException
310      */
311     public ResponseStream sendSync(HttpRequest.HttpMethod method, String url, RequestParams params) throws HttpException {
312         if (url == null) throw new IllegalArgumentException("url may not be null");
313 
314         HttpRequest request = new HttpRequest(method, url);
315         return sendSyncRequest(request, params);
316     }
317 
318     // ***************************************** download  下载*******************************************
319 
320     /**
321      * 下载文件方法
322      * @param url 下载文件的url
323      * @param target 下载保存的目录
324      * @param callback 回调
325      * @return
326      */
327     public HttpHandler<File> download(String url, String target,
328                                       RequestCallBack<File> callback) {
329         return download(HttpRequest.HttpMethod.GET, url, target, null, false, false, callback);
330     }
331 
332     /**
333      * 下载文件方法
334      * @param url 下载文件的url
335      * @param target 下载保存的目录
336      * @param autoResume 是否自动恢复下载
337      * @param callback 回调
338      * @return
339      */
340     public HttpHandler<File> download(String url, String target,
341                                       boolean autoResume, RequestCallBack<File> callback) {
342         return download(HttpRequest.HttpMethod.GET, url, target, null, autoResume, false, callback);
343     }
344 
345     /**
346      * 下载文件方法
347      * @param url 下载文件的url
348      * @param target 下载保存的目录
349      * @param autoResume  是否自动恢复下载
350      * @param autoRename 是否自动重命名
351      * @param callback 回调
352      * @return
353      */
354     public HttpHandler<File> download(String url, String target,
355                                       boolean autoResume, boolean autoRename, RequestCallBack<File> callback) {
356         return download(HttpRequest.HttpMethod.GET, url, target, null, autoResume, autoRename, callback);
357     }
358 
359     /**
360      * 下载文件方法
361      * @param url 下载文件的url
362      * @param target 下载保存的目录
363      * @param params 参数类
364      * @param callback 回调
365      * @return
366      */
367     public HttpHandler<File> download(String url, String target,
368                                       RequestParams params, RequestCallBack<File> callback) {
369         return download(HttpRequest.HttpMethod.GET, url, target, params, false, false, callback);
370     }
371 
372     /**
373      * 下载文件方法
374      * @param url  下载文件的url
375      * @param target 下载保存的目录
376      * @param params 参数类
377      * @param autoResume 是否自动恢复下载
378      * @param callback 回调
379      * @return
380      */
381     public HttpHandler<File> download(String url, String target,
382                                       RequestParams params, boolean autoResume, RequestCallBack<File> callback) {
383         return download(HttpRequest.HttpMethod.GET, url, target, params, autoResume, false, callback);
384     }
385 
386     /**
387      * 下载文件方法
388      * @param url 下载文件的url
389      * @param target 下载保存的目录
390      * @param params 参数
391      * @param autoResume 是否自动恢复
392      * @param autoRename 是否自动命名
393      * @param callback 回调
394      * @return
395      */
396     public HttpHandler<File> download(String url, String target,
397                                       RequestParams params, boolean autoResume, boolean autoRename, RequestCallBack<File> callback) {
398         return download(HttpRequest.HttpMethod.GET, url, target, params, autoResume, autoRename, callback);
399     }
400 
401     /**
402      * 下载文件方法
403      * @param method 请求用get还是post等
404      * @param url 下载文件的url
405      * @param target 下载保存的目录
406      * @param params 参数
407      * @param callback 回调
408      * @return
409      */
410     public HttpHandler<File> download(HttpRequest.HttpMethod method, String url, String target,
411                                       RequestParams params, RequestCallBack<File> callback) {
412         return download(method, url, target, params, false, false, callback);
413     }
414 
415     /**
416      * 下载文件方法
417      * @param method 请求用get还是post等
418      * @param url 下载文件的url
419      * @param target 下载保存的目录
420      * @param params 参数
421      * @param autoResume 是否自动恢复下载
422      * @param callback 回调
423      * @return
424      */
425     public HttpHandler<File> download(HttpRequest.HttpMethod method, String url, String target,
426                                       RequestParams params, boolean autoResume, RequestCallBack<File> callback) {
427         return download(method, url, target, params, autoResume, false, callback);
428     }
429 
430     /**
431      * 下载文件方法
432      * @param method 请求用get还是post等
433      * @param url 下载文件的url
434      * @param target 下载保存的目录
435      * @param params 参数
436      * @param autoResume 是否自动恢复下载
437      * @param autoRename 是否自动重命名
438      * @param callback 回调
439      * @return
440      */
441     public HttpHandler<File> download(HttpRequest.HttpMethod method, String url, String target,
442                                       RequestParams params, boolean autoResume, boolean autoRename, RequestCallBack<File> callback) {
443 
444         if (url == null) throw new IllegalArgumentException("url may not be null");
445         if (target == null) throw new IllegalArgumentException("target may not be null");
446 
447         HttpRequest request = new HttpRequest(method, url);
448 
449         HttpHandler<File> handler = new HttpHandler<File>(httpClient, httpContext, responseTextCharset, callback);
450 
451         handler.setExpiry(currentRequestExpiry);
452         handler.setHttpRedirectHandler(httpRedirectHandler);
453 
454         if (params != null) {
455             request.setRequestParams(params, handler);
456             handler.setPriority(params.getPriority());
457         }
458         handler.executeOnExecutor(EXECUTOR, request, target, autoResume, autoRename);
459         return handler;
460     }
461 
462     ////////////////////////////////////////////////////////////////////////////////////////////////
463     private <T> HttpHandler<T> sendRequest(HttpRequest request, RequestParams params, RequestCallBack<T> callBack) {
464 
465         HttpHandler<T> handler = new HttpHandler<T>(httpClient, httpContext, responseTextCharset, callBack);
466 
467         handler.setExpiry(currentRequestExpiry);
468         handler.setHttpRedirectHandler(httpRedirectHandler);
469         request.setRequestParams(params, handler);
470 
471         if (params != null) {
472             handler.setPriority(params.getPriority());
473         }
474         handler.executeOnExecutor(EXECUTOR, request);
475         return handler;
476     }
477 
478     private ResponseStream sendSyncRequest(HttpRequest request, RequestParams params) throws HttpException {
479 
480         SyncHttpHandler handler = new SyncHttpHandler(httpClient, httpContext, responseTextCharset);
481 
482         handler.setExpiry(currentRequestExpiry);
483         handler.setHttpRedirectHandler(httpRedirectHandler);
484         request.setRequestParams(params);
485 
486         return handler.sendRequest(request);
487     }
488 }

 

3. HttpUtils使用post/get 方法访问网络

(1)新建一个Android工程,命名为"HttpUtils",如下:

 

(2)首先我们来到主布局文件,如下:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical"
 6     tools:context="com.himi.httputils.MainActivity" >
 7 
 8     <Button
 9         android:id="@+id/net"
10         android:layout_width="match_parent"
11         android:layout_height="wrap_content"
12         android:text="@string/replynet" />
13     
14     <TextView
15         android:id="@+id/loading"
16         android:layout_width="match_parent"
17         android:layout_height="wrap_content"/>
18     
19     <ScrollView 
20         android:layout_width="fill_parent"
21         android:layout_height="wrap_content">
22         
23         <TextView
24         android:id="@+id/success"
25         android:layout_width="match_parent"
26         android:layout_height="wrap_content"/>
27         
28     </ScrollView>
29      
30 </LinearLayout>

(3)下面来到AndroidManifest.xml配置文件,添加权限。如下:

 

 

 

(4)来到MainActivity,如下:

 1 package com.himi.httputils;
 2 
 3 import com.lidroid.xutils.HttpUtils;
 4 import com.lidroid.xutils.ViewUtils;
 5 import com.lidroid.xutils.exception.HttpException;
 6 import com.lidroid.xutils.http.ResponseInfo;
 7 import com.lidroid.xutils.http.callback.RequestCallBack;
 8 import com.lidroid.xutils.http.client.HttpRequest;
 9 import com.lidroid.xutils.view.annotation.ViewInject;
10 import com.lidroid.xutils.view.annotation.event.OnClick;
11 
12 import android.app.Activity;
13 import android.os.Bundle;
14 import android.os.Handler;
15 import android.os.Message;
16 import android.view.View;
17 import android.widget.Button;
18 import android.widget.TextView;
19 
20 public class MainActivity extends Activity {
21 
22     @ViewInject(R.id.net)
23     private Button net;
24     
25     @ViewInject(R.id.loading)
26     private TextView loading;
27     
28     @ViewInject(R.id.success)
29     private TextView success;
30     
31     /**
32      * handler线程是主要用来和UI主线程进行交互的
33      *//*
34     private Handler handler = new Handler(){
35          public void handleMessage(Message msg) {
36                 super.handleMessage(msg);
37                 switch (msg.what) {
38                 case 1:
39          
40                     break;
41                 default:
42                     break;
43                 }
44             };
45     };*/
46     
47 
48     @Override
49     protected void onCreate(Bundle savedInstanceState) {
50         super.onCreate(savedInstanceState);
51         setContentView(R.layout.activity_main);
52         ViewUtils.inject(this);
53     }
54 
55     @OnClick(R.id.net)
56     public void reply(View v) {
57         
58                 HttpUtils http = new HttpUtils();
59                 http.send(HttpRequest.HttpMethod.GET, "http://www.lidroid.com", new RequestCallBack<String>() {
60                     @Override
61                     public void onLoading(long total, long current, boolean isUploading) {        
62                         System.out.println("数据加载中……");
63                         //System.out.println(current + "/" + total);
64                         loading.setText(current + "/" + total);
65                     }
66 
67                     @Override
68                     public void onSuccess(ResponseInfo<String> responseInfo) {
69                         System.out.println("数据加载完毕……");
70                         //System.out.println(responseInfo.result);
71                         success.setText(responseInfo.result);
72                     }
73 
74                     @Override
75                     public void onStart() {
76                         System.out.println("数据开始加载……");
77                     }
78 
79                     @Override
80                     public void onFailure(HttpException error, String msg) {
81                         System.out.println("数据加载失败……");
82                     }
83                 });
84 
85             }
86     
87 }

布署程序到手机中,如下:

我们可以知道使用 HttpUtils 访问网络的时候不用new Thread一个子线程,HttpUtils内部自己实现了子线程

同时我们在RequestCallBack回调的方法中可以直接操作UI界面的更新

 

 

 

4. HttpUtils使用Get方法提交数据到服务器:

(1)首先我们搭建一个服务器平台,如下:

 

 

(2)我们先看看LoginServlet,如下:

 1 package web;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.ServletException;
 6 import javax.servlet.annotation.WebServlet;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 
11 /**
12  * Servlet implementation class LoginServlet
13  */
14 @WebServlet("/LoginServlet")
15 public class LoginServlet extends HttpServlet {
16     private static final long serialVersionUID = 1L;
17        
18  
19     /**
20      * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
21      */
22     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
23         String qq = request.getParameter("qq");
24         String password = request.getParameter("password");
25         System.out.println("qq:"+qq);
26         System.out.println("password:"+password);
27         
28 /**
29  * 模拟服务器操作,查询数据库,看qq和密码是否正确. 
30  * response.getOutputStream()获得一个输出流,向浏览器写入数据(提示数据).
31  * 这里是输出Output,服务器输出到浏览器
32  */
33         if("10086".equals(qq) && "123456".equals(password)) {
34             response.getOutputStream().write("Login Success".getBytes());
35         }else {
36             response.getOutputStream().write("Login Failed".getBytes());
37         }
38         
39    }
40 
41 
42 }

布署上面的web工程到Tomcat服务器上。

(3)接下来我们来到客户端,我们新建一个Android工程,如下:

 

 

(4)首先我们这里写了一个工具类StreamTools,如下:

 1 package com.himi.httputils01;
 2 
 3 import java.io.ByteArrayOutputStream;
 4 import java.io.InputStream;
 5 
 6 /**
 7  * 流的工具类
 8  * @author Administrator
 9  *
10  */
11 public class StreamTools {
12     /**
13      * 把输入流的内容转换成字符串
14      * @param is
15      * @return null解析失败, string读取成功
16      */
17     public static String readStream(InputStream is) throws Exception {
18             ByteArrayOutputStream baos = new ByteArrayOutputStream();
19             byte[] buffer = new byte[1024];
20             int len = 0;
21             while((len = is.read(buffer)) != -1) {
22                 baos.write(buffer, 0, len);
23             }
24             is.close();
25             String result = baos.toString();
26             baos.close();
27             return result;
28             
29         
30     }
31 }

(5)我们首先来到主布局文件activity_main.xml,如下:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent"
 4     android:gravity="center_horizontal"
 5     android:paddingLeft="10dp"
 6     android:paddingRight="10dp"
 7     android:orientation="vertical" >
 8 
 9     <ImageView
10         android:layout_width="50dip"
11         android:layout_height="50dip"
12         android:src="@drawable/ic_launcher" />
13 
14     <EditText
15         android:id="@+id/et_qq"
16         android:inputType="text"
17         android:layout_width="match_parent"
18         android:layout_height="wrap_content"
19         android:hint="请输入qq号码" />
20     
21      <EditText
22          android:id="@+id/et_pwd"
23          android:layout_width="match_parent"
24          android:layout_height="wrap_content"
25          android:hint="请输入密码"
26          android:inputType="textPassword" />
27      
28      <CheckBox 
29          android:id="@+id/cb_remember"
30            android:layout_width="match_parent"
31          android:layout_height="wrap_content"
32          android:text="记住密码"
33          />
34 
35      <Button
36          android:onClick="login" 
37          android:layout_width="match_parent"
38          android:layout_height="wrap_content"
39          android:text="登陆"
40          
41          />
42 </LinearLayout>

布局效果如下:

(6)接下来我们来到MainActivity,如下:

  1 package com.himi.httputils01;
  2 
  3 import java.io.BufferedReader;
  4 import java.io.File;
  5 import java.io.FileInputStream;
  6 import java.io.FileOutputStream;
  7 import java.io.InputStreamReader;
  8 import java.net.MalformedURLException;
  9 import java.net.URL;
 10 
 11 import com.lidroid.xutils.HttpUtils;
 12 import com.lidroid.xutils.exception.HttpException;
 13 import com.lidroid.xutils.http.ResponseInfo;
 14 import com.lidroid.xutils.http.callback.RequestCallBack;
 15 import com.lidroid.xutils.http.client.HttpRequest;
 16 
 17 import android.app.Activity;
 18 import android.os.Bundle;
 19 import android.text.TextUtils;
 20 import android.util.Log;
 21 import android.view.View;
 22 import android.widget.CheckBox;
 23 import android.widget.EditText;
 24 import android.widget.Toast;
 25 
 26 public class MainActivity extends Activity {
 27     private static final String Tag = "MainActivity";
 28     private EditText et_qq;
 29     private EditText et_pwd;
 30     private CheckBox cb_remember;
 31 
 32     @Override
 33     protected void onCreate(Bundle savedInstanceState) {
 34         super.onCreate(savedInstanceState);
 35         setContentView(R.layout.activity_main);
 36         // 查询关心的控件
 37         et_qq = (EditText) findViewById(R.id.et_qq);
 38         et_pwd = (EditText) findViewById(R.id.et_pwd);
 39         cb_remember = (CheckBox) findViewById(R.id.cb_remember);
 40         Log.i(Tag, "oncreate 被调用");
 41 
 42         // 完成数据的回显。
 43         readSavedData();
 44     }
 45 
 46     // 读取保存的数据
 47     private void readSavedData() {
 48         // getFilesDir() == /data/data/包名/files/ 获取文件的路径 一般系统是不会清理的。
 49         // 用户手工清理,系统会有提示。
 50         // getCacheDir()== /data/data/包名/cache/ 缓存文件的路径 当系统内存严重不足的时候 系统会自动的清除缓存
 51         // 用户手工清理系统没有提示
 52         File file = new File(getFilesDir(), "info.txt");
 53         if (file.exists() && file.length() > 0) {
 54             try {
 55                 // FileInputStream fis = new FileInputStream(file);
 56                 FileInputStream fis = this.openFileInput("info.txt");
 57                 BufferedReader br = new BufferedReader(new InputStreamReader(fis));
 58                 // 214342###abcdef
 59                 String info = br.readLine();
 60                 String qq = info.split("###")[0];
 61                 String pwd = info.split("###")[1];
 62                 et_qq.setText(qq);
 63                 et_pwd.setText(pwd);
 64                 fis.close();
 65             } catch (Exception e) {
 66                 e.printStackTrace();
 67             }
 68         }
 69     }
 70 
 71     /**
 72      * 登陆按钮的点击事件,在点击事件里面获取数据
 73      * 
 74      * @param view
 75      */
 76     public void login(View view) {
 77         final String qq = et_qq.getText().toString().trim();
 78         final String pwd = et_pwd.getText().toString().trim();
 79         if (TextUtils.isEmpty(qq) || TextUtils.isEmpty(pwd)) {
 80             Toast.makeText(this, "qq号码或者密码不能为空", 0).show();
 81             return;
 82         }
 83         // 判断用户是否勾选记住密码。
 84         if (cb_remember.isChecked()) {
 85             // 保存密码
 86             Log.i(Tag, "保存密码");
 87             try {
 88                 // File file = new File(getFilesDir(),"info.txt");
 89                 // FileOutputStream fos = new FileOutputStream(file);
 90                 FileOutputStream fos = this.openFileOutput("info.txt", 0);
 91                 // 214342###abcdef
 92                 fos.write((qq + "###" + pwd).getBytes());
 93                 fos.close();
 94                 Toast.makeText(this, "保存成功", 0).show();
 95             } catch (Exception e) {
 96                 e.printStackTrace();
 97                 Toast.makeText(this, "保存失败", 0).show();
 98             }
 99         } else {
100             // 无需保存密码
101             Log.i(Tag, "无需保存密码");
102         }
103 
104         
105          /**
106           * 传统方法:使用子线程访问网络
107           */
108         /*new Thread() {
109             public void run() {
110                 // String path
111                 // ="http://localhost:8080/web/LoginServlet";这里不能写成localhost
112                 try {
113                     String path = getString(R.string.serverip);
114                     URL url = new URL(path + "?qq=" + qq + "&password=" + pwd);
115                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();
116 
117                     conn.setRequestMethod("GET");
118                     int code = conn.getResponseCode();
119                     if (code == 200) {
120                         InputStream is = conn.getInputStream();
121                         String result = StreamTools.readStream(is);
122                         showToastInAnyThread(result);
123                     } else {
124                         showToastInAnyThread("请求失败");
125                     }
126                 } catch (Exception e) {
127                     e.printStackTrace();
128                     showToastInAnyThread("请求失败");
129                 }
130             };
131 
132         }.start();*/
133 
134         /**
135          * 使用HttpUtils Get方式访问网络
136          */
137         
138         HttpUtils http = new HttpUtils();
139         String path = getString(R.string.serverip);
140         URL url = null;
141         try {
142             url = new URL(path+"?qq="+ qq + "&password="+pwd);
143         } catch (MalformedURLException e) {
144             // TODO Auto-generated catch block
145             e.printStackTrace();
146         }
147 
148         http.send(HttpRequest.HttpMethod.GET, url.toString(),
149                 new RequestCallBack<String>() {
150 
151             @Override
152             public void onFailure(HttpException arg0, String arg1) {
153                 showToastInAnyThread("提交数据失败");
154 
155             }
156 
157             @Override
158             public void onSuccess(ResponseInfo<String> arg0) {
159                 showToastInAnyThread("提交数据成功");
160 
161             }
162 
163         });
164 
165     }
166 
167     /**
168      * 显示土司 在主线程更新UI
169      * 
170      * @param text
171      */
172     public void showToastInAnyThread(final String text) {
173         runOnUiThread(new Runnable() {
174 
175             @Override
176             public void run() {
177                 Toast.makeText(MainActivity.this, text, 0).show();
178 
179             }
180         });
181     }
182 }

上面使用到res/values/string.xml,如下:

1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3 
4     <string name="app_name">HttpUtils01</string>
5     <string name="hello_world">Hello world!</string>
6     <string name="action_settings">Settings</string>
7     <string name="serverip">http://49.123.72.28:8088/web/LoginServlet</string>
8 
9 </resources>

 

(7)这里需要网络权限

(8)布署程序到模拟器上,如下:

 

输入账号密码,如下:

保存账号到手机内存data/data/包名/files目录下,如下:

 

导出info.txt,查看里面内容如下:

 

 

 

我们查看服务器端,说明提交数据到服务器端成功。如下:

 

 

5. 使用HttpUtils下载文件

  • 支持断点续传,随时停止下载任务,开始任务

(1)开启Apache服务器,如下:

(2)在Apache服务器安装(解压)目录下htdocs存放文件夹movies,文件夹内部存放一个MP4文件,如下:

 

 

(3)新建一个Android工程,如下:

 

 

(4)首先我们来到主布局文件,如下:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:orientation="vertical"
 6     tools:context=".MainActivity" >
 7 
 8     <Button
 9         android:text="下载"
10         android:layout_width="match_parent"
11         android:layout_height="wrap_content"
12         android:layout_marginTop="10dip"
13         android:onClick="download" />
14     <Button
15         android:text="取消"
16         android:layout_width="match_parent"
17         android:layout_height="wrap_content"
18         android:layout_marginTop="10dip"
19         android:onClick="cancel_download" />
20 
21     <TextView
22         android:id="@+id/tv_info"
23         android:layout_width="match_parent"
24         android:layout_height="wrap_content"
25         android:layout_marginTop="10dip"
26         android:text="提示信息" />
27 
28 </LinearLayout>

 

(5)这里需要使用 网络,则在AndroidManifest.xml中添加相应的权限,如下:

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

 

 

(6)接着,我们来到MainActivity,如下:

 1 package com.himi.httputils02;
 2 
 3 import java.io.File;
 4 
 5 import com.lidroid.xutils.HttpUtils;
 6 import com.lidroid.xutils.exception.HttpException;
 7 import com.lidroid.xutils.http.HttpHandler;
 8 import com.lidroid.xutils.http.ResponseInfo;
 9 import com.lidroid.xutils.http.callback.RequestCallBack;
10 
11 import android.app.Activity;
12 import android.os.Bundle;
13 import android.view.View;
14 import android.widget.TextView;
15 
16 public class MainActivity extends Activity {
17 
18     private TextView tv;
19     
20     private HttpHandler handler;
21 
22     @Override
23     protected void onCreate(Bundle savedInstanceState) {
24         super.onCreate(savedInstanceState);
25         setContentView(R.layout.activity_main);
26 
27         tv = (TextView) findViewById(R.id.tv_info);
28     }
29 
30     public void download(View v) {
31         String download_url = getString(R.string.source_url);
32         String target_url = getString(R.string.target_url);
33         HttpUtils http = new HttpUtils();
34         /**
35          * 下载文件方法
36          * 
37          * @param url
38          *            下载文件的url
39          * @param target
40          *            下载保存的目录
41          * @param autoResume
42          *            是否自动恢复下载
43          * @param autoRename
44          *            是否自动重命名
45          * @param callback
46          *            回调
47          * @return
48          */
49          handler = http.download(download_url, target_url, true, // 如果目标文件存在,接着未完成的部分继续下载。服务器不支持RANGE时将从新下载
50                 true, // 如果从请求返回信息中获取到文件名,下载完成后自动重命名
51                 new RequestCallBack<File>() {
52 
53                     @Override
54                     public void onStart() {
55                         tv.setText("conn...");
56                     }
57 
58                     @Override
59                     public void onLoading(long total, long current, boolean isUploading) {
60                         //当然这里也可以使用进度条
61                         tv.setText(current + "/" + total);
62                         
63                     }
64 
65                     @Override
66                     public void onSuccess(ResponseInfo<File> responseInfo) {
67                         tv.setText("downloaded:" + responseInfo.result.getPath());
68                     }
69 
70                     @Override
71                     public void onFailure(HttpException error, String msg) {
72                         tv.setText(msg);
73                     }
74                 });
75     }
76     
77     public void cancel_download(View v){
78         //调用cancel()方法停止下载
79         handler.cancel();
80         tv.setText("It's canceled");
81     }
82 
83 }

 

(7)布署程序到模拟器上,如下:

  • 点击"下载",等待下载成功

我们追踪data/data/com.himi.httputils02/files/video.mp4,如下:

 

 

 

 

  • 点击"下载"没有下载完,就点击"取消".

 

观察比较下载中断之后的数据原来服务器端的数据大小,结果如下:

posted on 2016-04-28 08:24  鸿钧老祖  阅读(1134)  评论(0编辑  收藏  举报

导航