1.FinalHttp是什么 :FinalHttp 对 HttpClient再次封装,最简洁的就是增加了许多回调的方法,对Get 和 Post 请求进行了简化。另外一点就是FinalHttp加入线程池操作,默认的Http请求池连接为3。下面是为FinalHttp可配置的操作。




1


2


3


4


5


6


7


8




​FinalHttp finalHttp = ​​​​new​​ ​​FinalHttp();​


​finalHttp.addHeader(​​​​"Accept-Charset"​​​​, ​​​​"UTF-8"​​​​);​​​​//配置http请求头​


​finalHttp.configCharset(​​​​"UTF-8"​​​​);​


​finalHttp.configCookieStore(​​​​null​​​​);​


​finalHttp.configRequestExecutionRetryCount(​​​​3​​​​);​​​​//请求错误重试次数​


​finalHttp.configSSLSocketFactory(​​​​null​​​​);​


​finalHttp.configTimeout(​​​​5000​​​​);​​​​//超时时间​


​finalHttp.configUserAgent(​​​​"Mozilla/5.0"​​​​);​​​​//配置客户端信息​



 


2.FinalHttp 之 Get




​?​



1


2


3


4


5


6


7


8


9


10


11


12


13


14




​//------------------get 请求-----------------------​


​public​​ ​​void​​ ​​get( String url, AjaxCallBack<? ​​​​extends​​ ​​Object> callBack) {​


​get( url, ​​​​null​​​​, callBack);​


​}​


 


​public​​ ​​void​​ ​​get( String url, AjaxParams params, AjaxCallBack<? ​​​​extends​​ ​​Object> callBack) {​


​sendRequest(httpClient, httpContext, ​​​​new​​ ​​HttpGet(getUrlWithQueryString(url, params)), ​​​​null​​​​, callBack);​


​}​


 


​public​​ ​​void​​ ​​get( String url, Header[] headers, AjaxParams params, AjaxCallBack<? ​​​​extends​​ ​​Object> callBack) {​


​HttpUriRequest request = ​​​​new​​ ​​HttpGet(getUrlWithQueryString(url, params));​


​if​​​​(headers != ​​​​null​​​​) request.setHeaders(headers);​


​sendRequest(httpClient, httpContext, request, ​​​​null​​​​, callBack);​


​}​



 


三个方法的却别在于:第二个增加了参数。第三个增加了http header。,此处,AjaxParams 是一个 map集合。来看看 sendRequest方法。




1


2


3


4


5


6


7


8


9




​protected​​ ​​<T> ​​​​void​​ ​​sendRequest(DefaultHttpClient client, HttpContext httpContext, HttpUriRequest uriRequest, String contentType, AjaxCallBack<T> ajaxCallBack) {​


​if​​​​(contentType != ​​​​null​​​​) {​


​uriRequest.addHeader(​​​​"Content-Type"​​​​, contentType);​


​}​


 


​new​​ ​​HttpHandler<T>(client, httpContext, ajaxCallBack,charset)​


​.executeOnExecutor(executor, uriRequest);​


 


​}​



 


这里面 直接调用了一个类HttpHandler的executeOnExecutor方法,传入了一个重要的参数executor。看看这个类:HttpHandler





1


2


3


4


5


6


7


8


9


10


11


12




​public​​ ​​class​​  ​​HttpHandler  <T> ​​​​extends​​  ​​AsyncTask<Object, Object, Object> ​​​​implements​​ ​​EntityCallBack{​


 


​private​​ ​​final​​ ​​AjaxCallBack<T> callback;​


 


​private​​ ​​int​​ ​​executionCount = ​​​​0​​​​;​


 


​public​​ ​​HttpHandler(AbstractHttpClient client, HttpContext context, AjaxCallBack<T> callback,String charset) {​


​this​​​​.client = client;​


​this​​​​.context = context;​


​this​​​​.callback = callback;​


​this​​​​.charset = charset;​


​}​



 



这个类继承了 AsyncTask,这个 AsyncTask是作者 自定义的,它相对于android 自带的 AsyncTask:修改了线程池属性,让并发线程按顺序执行。之前好像有人提到使用 afinal 加载图片是一个一个加载的,原因可能就在这里了。

这个类还实现了自定义的一个接口,里面的这个方法是我们回调的方法:



1


2


3




​public​​ ​​interface​​ ​​EntityCallBack {​


​public​​ ​​void​​ ​​callBack(​​​​long​​ ​​count,​​​​long​​ ​​current,​​​​boolean​​ ​​mustNoticeUI);​


​}​



 


这表明了HttpHandler 是一个异步加载类,我精简掉方法中暂时不用的代码,很显然,他的异步方法应该在 这个方法中执行doInBackground:




​?​



1


2


3


4


5


6


7


8


9


10


11


12


13




​@Override​


​protected​​ ​​Object doInBackground(Object... params) {​


 


​try​​ ​​{​


​publishProgress(UPDATE_START); ​​​​// 开始​


​makeRequestWithRetries((HttpUriRequest)params[​​​​0​​​​]);​​​​//调用​


 


​} ​​​​catch​​ ​​(IOException e) {​


​publishProgress(UPDATE_FAILURE,e,​​​​0​​​​,e.getMessage()); ​​​​// 结束​


​}​


 


​return​​ ​​null​​​​;​


​}​






​?​



1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33




​private​​ ​​void​​ ​​makeRequestWithRetries(HttpUriRequest request) ​​​​throws​​ ​​IOException {​


 


​boolean​​ ​​retry = ​​​​true​​​​;​


​IOException cause = ​​​​null​​​​;​


​HttpRequestRetryHandler retryHandler = client.getHttpRequestRetryHandler();​


​while​​ ​​(retry) {​


​try​​ ​​{​


​if​​ ​​(!isCancelled()) {​


​[color=Red]HttpResponse response = client.execute(request, context);[/color]​​​​//这里就开始执行了​


​if​​ ​​(!isCancelled()) {​


​handleResponse(response);​


​} ​


​}​


​return​​​​;​


​} ​​​​catch​​ ​​(UnknownHostException e) {​


​publishProgress(UPDATE_FAILURE,e,​​​​0​​​​,​​​​"unknownHostException:can't resolve host"​​​​);​


​return​​​​;​


​} ​​​​catch​​ ​​(IOException e) {​


​cause = e;​


​retry = retryHandler.retryRequest(cause, ++executionCount,context);​


​} ​​​​catch​​ ​​(NullPointerException e) {​


​cause = ​​​​new​​ ​​IOException(​​​​"NPE in HttpClient"​​ ​​+ e.getMessage());​


​retry = retryHandler.retryRequest(cause, ++executionCount,context);​


​}​​​​catch​​ ​​(Exception e) {​


​cause = ​​​​new​​ ​​IOException(​​​​"Exception"​​ ​​+ e.getMessage());​


​retry = retryHandler.retryRequest(cause, ++executionCount,context);​


​}​


​}​


​if​​​​(cause!=​​​​null​​​​)​


​throw​​ ​​cause;​


​else​


​throw​​ ​​new​​ ​​IOException(​​​​"未知网络错误"​​​​);​


​}​



HttpResponse response = client.execute(request, context);这就开始执行了。

retry = retryHandler.retryRequest(cause, ++executionCount,context);这里出现异常执行一次,次数加一次。直到你设置的次数超过为止,retryHandler 就会直接返回false 中断 while(retry)