Afinalandroid
這是Afinal在github的地址:https://github.com/yangfuhai/afinalgit
Afinal這個框架主要分4塊:github
一、FinalDB模塊:android中的orm框架,一行代碼就能夠進行增刪改查。支持一對多,多對一等查詢。ajax
二、FinalActivity模塊:android中的ioc框架,徹底註解方式就能夠進行UI綁定和事件綁定。無需findViewById和setClickListener等。算法
三、FinalHttp模塊:經過httpclient進行封裝http數據請求,支持ajax方式加載。緩存
四、FinalBitmap模塊:經過FinalBitmap,imageview加載bitmap的時候無需考慮bitmap加載過程當中出現的oom和android容器快速滑動時候出現的圖片錯位等現象。FinalBitmap能夠配置線程加載線程數量,緩存大小,緩存路徑,加載顯示動畫等。FinalBitmap的內存管理使用lru算法,沒有使用弱引用(android2.3之後google已經不建議使用弱引用,android2.3後強行回收軟引用和弱引用,詳情查看android官方文檔),更好的管理bitmap內存。FinalBitmap能夠自定義下載器,用來擴展其餘協議顯示網絡圖片,好比ftp等。同時能夠自定義bitmap顯示器,在imageview顯示圖片的時候播放動畫等(默認是漸變更畫顯示)。網絡
這裏咱們先講FinalHttp模塊,這是它的用法:框架
AjaxParams params = new AjaxParams(); params.put("username", "michael yang"); params.put("password", "123456"); params.put("email", "test@tsz.net"); params.put("profile_picture", new File("/mnt/sdcard/pic.jpg")); // 上傳文件 params.put("profile_picture2", inputStream); // 上傳數據流 params.put("profile_picture3", new ByteArrayInputStream(bytes)); // 提交字節流 FinalHttp fh = new FinalHttp(); fh.post("http://www.yangfuhai.com", params, new AjaxCallBack(){ @Override public void onLoading(long count, long current) { textView.setText(current+"/"+count); } @Override public void onSuccess(String t) { textView.setText(t==null?"null":t); } });
你們看到了吧,fh.get(baseUrl, params, new AjaxCallBack(){});ide
這句話的底層就是HttpClient執行HttpGet或者HttpPost請求的一個封裝,其中baseUrl+params拼湊起來就是url,然後面的AjaxCallBack就是對HttpClient對http請求獲得的一個HttpResponse響應結果的分析回調。函數
咱們來看具體的流程步驟:
第一步:初始化FinalHttp,而後執行get()方法
public void get( String url, AjaxParams params, AjaxCallBack<? extends Object> callBack) { sendRequest(httpClient, httpContext, new HttpGet(getUrlWithQueryString(url, params)), null, callBack); }
第二步:咱們看sendRequest()這個方法,這個方法就是把get方法裏的參數傳遞到這個函數,而後發起http請求。
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裏的exe方法。咱們看到這個方法的參數有DefaultHttpClient,這個都不用說了你們都很熟悉,HttpContext就是一個上下文,HttpUriRequest就是一個get,put,delete,post等http請求,而後就是添加頭部信息,好比要不要進行壓縮,這裏貌似用了zip壓縮使得傳輸速率更快,再後面就是回調函數接口,判斷請求是否成功失敗等。
第三步:進入HttpHandler類,這是一個處理http請求的類。這個類是繼承AsyncTask,可是這個AsyncTask類並非原生的,而是通過做者精心修改的。沒有深刻去看AsyncTask,大略看了一下,貌似doInBackground這個方法是放進一個線程池裏去執行的。這個線程池配置的很精細,就像批量加載圖片那個例子,能夠只想你個完上一個線程,就立刻執行下一個任務。
1.這個類還實現了EntityCallBack回調接口,而且接收了AjaxCallBack這個回調實例。咱們先看doInBackground方法。
protected Object doInBackground(Object... params) { if(params!=null && params.length == 3){ targetUrl = String.valueOf(params[1]); isResume = (Boolean) params[2]; } try { publishProgress(UPDATE_START); // 開始 makeRequestWithRetries((HttpUriRequest)params[0]); } catch (IOException e) { publishProgress(UPDATE_FAILURE,e,e.getMessage()); // 結束 } return null; }
2.能夠看到真正執行的方法是makeRequestWithRetries(HttpUriRequest *)方法,進去看看先
private void makeRequestWithRetries(HttpUriRequest request) throws IOException { if(isResume && targetUrl!= null){ File downloadFile = new File(targetUrl); long fileLen = 0; if(downloadFile.isFile() && downloadFile.exists()){ fileLen = downloadFile.length(); } if(fileLen > 0) request.setHeader("RANGE", "bytes="+fileLen+"-"); } boolean retry = true; IOException cause = null; HttpRequestRetryHandler retryHandler = client.getHttpRequestRetryHandler(); while (retry) { try { if (!isCancelled()) { HttpResponse response = client.execute(request, context); if (!isCancelled()) { handleResponse(response); } } return; } catch (UnknownHostException e) { publishProgress(UPDATE_FAILURE, e,"unknownHostException:can't resolve host"); return; } catch (IOException e) { cause = e; retry = retryHandler.retryRequest(cause, ++executionCount,context); } catch (NullPointerException e) { // HttpClient 4.0.x 以前的一個bug // http://code.google.com/p/android/issues/detail?id=5255 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("未知網絡錯誤"); }
其中isResume是斷點續傳標誌,targetUrl判斷是文件的話就添加文件大小頭部信息。retry是遇到錯誤是否要重試標誌,FinalHttp有這個參數配置,能夠設置重試次數。而後就是HttpClient執行Http請求獲取響應的操做,若是這個過程當中UI上的交互有取消操做的話。能夠經過isCancelled()這個方法得知從而取消請求。若是請求順利會獲得一個HttpResponse,而處理這個響應結果是handleResponse()方法。
3.這是專門處理響應結果的方法
private void handleResponse(HttpResponse response) { StatusLine status = response.getStatusLine(); if (status.getStatusCode() >= 300) { String errorMsg = "response status error code:"+status.getStatusCode(); if(status.getStatusCode() == 416 && isResume){ errorMsg += " \n maybe you have download complete."; } publishProgress(UPDATE_FAILURE,new HttpResponseException(status.getStatusCode(), status.getReasonPhrase()),errorMsg); } else { try { HttpEntity entity = response.getEntity(); Object responseBody = null; if (entity != null) { time = SystemClock.uptimeMillis(); if(targetUrl!=null){ responseBody = mFileEntityHandler.handleEntity(entity,this,targetUrl,isResume); } else{ responseBody = mStrEntityHandler.handleEntity(entity,this,charset); } } publishProgress(UPDATE_SUCCESS,responseBody); } catch (IOException e) { publishProgress(UPDATE_FAILURE,e,e.getMessage()); } } }
經過狀態碼,判斷成功後處理獲得的HttpEntity。若是這個response是字符串就由StringEntityHandler這個類去解析,若是是文件就是FileEntityHandler解析。獲得結果後,就是publishProgress去推送了,這個方法在前面的方法中都看到有被調用。稍微對AsyncTask熟悉的人就知道這個方法將能夠觸發onProgressUpdate(* value).這個方法就是告訴你執行的進度,AfinalHttp中AjaxCallback中的onSuccess,onFailure等方法就是根據這個來觸發的。
private final static int UPDATE_START = 1; private final static int UPDATE_LOADING = 2; private final static int UPDATE_FAILURE = 3; private final static int UPDATE_SUCCESS = 4;
到這裏這個過程就完成了。
看到這麼多的處理,會以爲這樣是否是會更慢。一個網絡請求處理的極其複雜,想FinalHttp不少默認的配置和繁雜的處理響應並通知處理進程,其實這樣多多少少拖慢了請求的速度。在實際應用尤爲感覺深切,一遇到網絡慢,跨地域幅度大等教爲惡劣的網絡環境,AFinal就有點顯得捉襟見肘了。
因爲篇幅限制,此次就講這麼多了。
http://blog.csdn.net/bvin_/article/details/10914197