Xutils 源碼解析

1. 功能介紹

xUtils一個Android公共庫框架,主要包括四個部分:View,Db, Http, Bitmap 四個模塊。 java

  • View模塊主要的功能是經過註解綁定UI,資源,事件。
  • Db模塊是一個數據庫orm框架, 簡單的語句就能進行數據的操做。
  • Http模塊主要訪問網絡,支持同步,異步方式的請求,支持文件的下載。
  • Bitmap模塊是加載圖片以及圖片的處理, 支持加載本地,網絡圖片。並且支持圖片的內存和本地緩存。

2. 詳細設計

2.1 View模塊

2.1.1 整體設計

流程和關係較少, 請看下面的詳細分析 android

2.1.2 流程圖

流程圖

2.1.3 核心類功能介紹
請先了解註解 ,動態代理 能夠幫助到您, 若是已經瞭解請忽略。

註解和反射知識是這個模塊的主要內容 git

1.ViewUtils.java

View和各類事件的注入以及資源的注入。 github

(1)主要函數
private static void injectObject(Object handler, ViewFinder finder)

第一個參數Object handler表明的是須要注入的對象, 第二個參數是須要注入View(這個View就是handler的成員變量)所在的View或者Activity的包裝對象。 該方法完成了View和各類事件的注入以及資源的注入。主要的原理就是經過反射和註解。 sql

  • 完成Activity的setContentView。
  • 完成View的注入。
  • 完成資源的注入。
  • 完成各類事件的注入。
2.ViewFinder.java
(1)主要函數
public View findViewById(int id, int pid)
    public View findViewById(int id)

若是存在父View, 優先從父View尋找,不然從當前的View或者Activity中尋找。 數據庫

3.ResLoader.java
public static Object loadRes(ResType type, Context context, int id)

獲取資源文件值。支持多種資源的獲取。 apache

4.EventListenerManager.java

事件的注入, 其中的設計是經過動態代理。 api

private final static DoubleKeyValueMap<ViewInjectInfo, Class<?>, Object> listenerCache =
            new DoubleKeyValueMap<ViewInjectInfo, Class<?>, Object>();

存放監聽事件接口map。 由於有些接口有多個函數, 代理會判斷事件接口是否存在, 若是存在只增長代理方法就夠了, 避免從新設置監聽事件接口。 緩存

public static void addEventMethod(
            ViewFinder finder,
            ViewInjectInfo info,
            Annotation eventAnnotation,
            Object handler,
            Method method)

代理監聽事件 服務器

5.註解類

2.2 Db模塊

2.2.1 整體設計

流程和關係較少, 請看下面的詳細分析

2.2.2 流程圖

流程圖

2.2.3 核心類功能介紹

註解、反射和數據庫操做知識這個模塊的主要內容

1.DbUtils.java

主要功能數據庫的建立,數據庫的增刪改查。

private static HashMap<String, DbUtils> daoMap = new HashMap<String, DbUtils>();

存放DbUtils實例對象的map,每一個數據庫對應一個實例, key爲數據庫的名稱。

private synchronized static DbUtils getInstance(DaoConfig daoConfig)

採起的是單例模式,根據DaoConfig建立數據庫, 中間還涉及到數據庫升級。

delete;
    findAll;
    findById;
    saveOrUpdate;// 當數據庫沒有時保存, 存在時修改。
    update;

增刪改查。

2.DaoConfig.java
private String dbName = "xUtils.db"; // default db name數據庫名稱
    private int dbVersion = 1; //數據庫版本
    private DbUpgradeListener dbUpgradeListener; //升級監聽事件

數據庫配置類。

3.FindTempCache.java

在DbUtils的查詢數據中

@SuppressWarnings("unchecked")
    public <T> List<T> findAll(Selector selector) throws DbException {
        ....

        String sql = selector.toString();
        long seq = CursorUtils.FindCacheSequence.getSeq();
        findTempCache.setSeq(seq);
        Object obj = findTempCache.get(sql);//優先從緩存讀取
        if (obj != null) {
            return (List<T>) obj;
        }

        ...
    }

數據庫查詢數據的緩存。在查詢中會優先調用緩存中的數據

4.SqlInfoBuilder.java

sql建表、增刪改語句的組合。

public static SqlInfo buildCreateTableSqlInfo(DbUtils db, Class<?> entityType)  
public static SqlInfo buildDeleteSqlInfo(DbUtils db, Class<?> entityType, Object idValue)
public static SqlInfo buildDeleteSqlInfo(DbUtils db, Class<?> entityType, WhereBuilder whereBuilder)
public static SqlInfo buildDeleteSqlInfo(DbUtils db, Object entity)
public static SqlInfo buildInsertSqlInfo(DbUtils db, Object entity)
public static SqlInfo buildUpdateSqlInfo(DbUtils db, Object entity, String... updateColumnNames)
public static SqlInfo buildUpdateSqlInfo(DbUtils db, Object entity, WhereBuilder whereBuilder, String... updateColumnNames)
5.SqlInfo.java

sql語句和值包裝對象。

6.Table.java

表對象。

7.Column.java

表中列對象。

8.Id.java

表對應的主鍵對象。

9.Selector.java

sql查詢語句的組合。

10.WhereBuilder.java

sql條件語句的組合。

2.3 Http模塊
2.3.1 整體設計

總體構建思路

2.3.2 流程圖

流程圖

2.3.3 類圖

流程圖

1.HttpUtils.java

支持異步同步訪問網絡數據, 斷點下載文件。

//網絡數據的緩存。
    public final static HttpCache sHttpCache = new HttpCache();
    //訪問網絡的HttpClient。
    private final DefaultHttpClient httpClient; 
    private final HttpContext httpContext = new BasicHttpContext();
    //線程池。
    private final static PriorityExecutor EXECUTOR = new PriorityExecutor(DEFAULT_POOL_SIZE);
public HttpUtils(int connTimeout, String userAgent) {
        //配置超時時間,UserAgent, http版本信息協議等一些信息
        .....
        //將配置的參數統一放到httpClient中
        httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager(params, schemeRegistry), params);
        ....

        //下面這個關鍵,設置攔截器。 默認加上gizp壓縮。 經過gizp壓縮後的數據傳輸效率高不少。
        httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
            @Override
            public void process(org.apache.http.HttpRequest httpRequest, HttpContext httpContext) throws org.apache.http.HttpException, IOException {
                if (!httpRequest.containsHeader(HEADER_ACCEPT_ENCODING)) { 
                    httpRequest.addHeader(HEADER_ACCEPT_ENCODING, ENCODING_GZIP);
                }
            }
        });

        httpClient.addResponseInterceptor(new HttpResponseInterceptor() {
            @Override
            public void process(HttpResponse response, HttpContext httpContext) throws org.apache.http.HttpException, IOException {
                final HttpEntity entity = response.getEntity();
                if (entity == null) {
                    return;
                }
                final Header encoding = entity.getContentEncoding();
                if (encoding != null) {
                    for (HeaderElement element : encoding.getElements()) {
                        if (element.getName().equalsIgnoreCase("gzip")) {
                            //這裏判斷從服務器傳輸的數據是否須要經過gzip解壓。
                            response.setEntity(new GZipDecompressingEntity(response.getEntity())); 
                            return;
                        }
                    }
                }
            }
        });
    }
//訪問網絡數據
    private <T> HttpHandler<T> sendRequest(HttpRequest request, RequestParams params, RequestCallBack<T> callBack);
    //下載網絡文件
    public HttpHandler<File> download(HttpRequest.HttpMethod method, String url, String target,
                                      RequestParams params, boolean autoResume, boolean autoRename, RequestCallBack<File> callback);
2.HttpRequest.java

網絡請求的包裝類。 包括url, 訪問請求方法, 參數值等。

3.RequestCallBack.java

完成數據請求回調接口。

4.HttpHandler.java

獲取網絡數據邏輯的實現。這裏能夠理解爲系統內部AsyncTask。 訪問網絡數據處理流程圖
流程圖

5.HttpCache.java

網絡數據的緩存,內部包含LruMemoryCache。在獲取數據的時候會判斷是否過時。

6.StringDownLoadHandler.java

handleEntity()將網絡io流轉化爲String。

7.FileDownLoadHandler.java

handleEntity()將網絡io流轉化爲File。

8.HttpException.java

統一異常

2.4 Bitmap模塊
2.4.1 整體設計

總體構建思路

2.4.2 流程圖

請查看http模塊

2.4.3 類圖

類圖

1.BitmapUtils.java

圖片的異步加載,支持本地和網絡圖片, 圖片的壓縮處理, 圖片的內存緩存已經本地緩存。

private BitmapGlobalConfig globalConfig; // 線程池,緩存,和網絡的配置
    private BitmapDisplayConfig defaultDisplayConfig; //圖片顯示的配置
/**
     * @param container 表示須要顯示圖片的View
     * @param uri 圖片的uri
     * @param displayConfig 圖片顯示的配置
     * @param callBack 圖片加載的回調接口
     */
    public <T extends View> void display(T container, String uri, BitmapDisplayConfig displayConfig, BitmapLoadCallBack<T> callBack)

設置圖片流程圖
流程圖

詳細流程圖
Bitmap詳細流程圖

2.BitmapLoadTask.java

加載圖片的異步任務。在doInBackground中讀取圖片資源

3.BitmapCache.java
private LruDiskCache mDiskLruCache; //閃存緩存
    private LruMemoryCache<MemoryCacheKey, Bitmap> mMemoryCache; //運存緩存
(1)主要函數
//下載網絡圖片, 而後根據配置壓縮圖片, 將圖片緩存。
    public Bitmap downloadBitmap(String uri, BitmapDisplayConfig config, final BitmapUtils.BitmapLoadTask<?> task)
    //從運存緩存中讀取bitmap 在獲取的時候會判斷是否過時
    public Bitmap getBitmapFromMemCache(String uri, BitmapDisplayConfig config)
    //從閃存緩存中讀取bitmap
    public Bitmap getBitmapFromDiskCache(String uri, BitmapDisplayConfig config)
4.BitmapGlobalConfig.java

配置, 包括線程池, 緩存的大小。

//閃存緩存的路徑
private String diskCachePath;
//運存緩存的最大值
private int memoryCacheSize = 1024 * 1024 * 4; // 4MB
//閃存緩存的最大值
private int diskCacheSize = 1024 * 1024 * 50;  // 50M
//從網絡加載數據的線程池
private final static PriorityExecutor BITMAP_LOAD_EXECUTOR = new PriorityExecutor(DEFAULT_POOL_SIZE);
//從閃存讀取數據的線程池
private final static PriorityExecutor DISK_CACHE_EXECUTOR = new PriorityExecutor(2);
//bitmap緩存的的時間
private long defaultCacheExpiry = 1000L * 60 * 60 * 24 * 30; // 30 days
//bitmap緩存
private BitmapCache bitmapCache;
5.BitmapDisplayConfig.java
//圖片顯示的大小
    private BitmapSize bitmapMaxSize;
    //圖片的動畫
    private Animation animation;
    // 圖片加載過程當中的顯示圖片
    private Drawable loadingDrawable;
    // 圖片加載失敗的顯示圖片
    private Drawable loadFailedDrawable;
    // 圖片顯示的配置色彩
    private Bitmap.Config bitmapConfig = Bitmap.Config.RGB_565;
6.DefaultDownloader.java

獲取bitmap, 支持三種獲取路徑, 本地文件,資產文件, 和網絡圖片。

7.DefaultBitmapLoadCallBack.java

圖片加載完成的的回調, 默認回調將獲取的bitmap值傳遞給view。

3. 雜談

和Volley框架相比

相同點:

  • 1.採用了網絡數據緩存機制。
  • 2.經過handler進行線程通訊

不一樣點:

    1. Volley的Http請求在 android 2.3 版本以前是經過HttpClient ,在以後的版本是經過URLHttpConnection。xUtils都是經過HttpClient請求網絡(bitmap模塊圖片下載是經過URLHttpConnection)。 URLHttpConnection默認支持GZIP壓縮,api操做簡單。
  • 2.Volley將Http請求數據先緩存進byte[], 而後是分配給不一樣的請求轉化爲須要的格式。xUtils是直接轉化爲想要的格式。 Volley:擴展性好, 可是不能存在大數據請求,不然就OOM。xUtils:不緩存入byte[] 支持大數據的請求, 速度比Volley稍快,但擴展性就低。
  • 4.Volley訪問網絡數據時直接開啓固定個數線程訪問網絡, 在run方法中執行死循環, 阻塞等待請求隊列。 xUtils是開啓線程池來管理線程。
    1. 緩存失效策略, volley的全部網絡數據支持從http響應頭中控制是否緩存和讀取緩存失效時間,每一個請求能夠控制是否緩存和緩存失效時間。 Xutils網絡數據請求是統一自定義緩存失效時間。
相關文章
相關標籤/搜索