介紹
經過最近的努力,將幾個常用框架進行了封裝,並抽成了一個安卓基礎開發庫 。
主要包括 網路請求、圖片載入、資料庫、事件匯流排、快取、許可權管理、工具類 模組。
其中,網路請求使用Retrofit+RxJava實現,圖片載入使用Glide實現(可替換),資料庫使用GreenDao實現(可替換),事件匯流排使用EventBus實現(可替換),許可權管理使用RxPermission實現。
Demo採用MVP+Dagger2進行開發,演示了各模組的使用。
對以上提及的框架如果不熟悉,建議先瞭解下~
如果覺得不錯,不妨點個star。你的支援,是我開源的動力~
使用說明
1. 新增依賴
在專案module下的gradle中新增以下依賴:
compile 'com.ljy.ring:devring:1.0.4'
複製程式碼
由於資料庫、圖片載入、事件匯流排模組支援替換其預設實現的框架, 所以庫中對GreenDao,Glide,EventBus的依賴是使用compileOnly(僅在編譯時依賴),這麼做是為了避免被替換的框架依然參與打包,從而增加了apk大小。
也就是說,對於這三個模組,當你需要使用相關框架時,還需新增其依賴。
如果要使用Devring庫的圖片載入模組(預設Glide),那麼需要新增Glide依賴
compile 'com.github.bumptech.glide:glide:4.4.0'
複製程式碼
如果要使用Devring庫的資料庫模組(預設GreenDao),那麼需要新增GreenDao依賴
//Project下的build.gradle檔案中加入
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.0'
複製程式碼
//Module下的build.gradle檔案中加入
apply plugin: 'org.greenrobot.greendao'
compile 'org.greenrobot:greendao:3.2.0'
複製程式碼
如果要使用Devring庫的事件匯流排模組(預設EventBus),那麼需要新增EventBus依賴
compile 'org.greenrobot:eventbus:3.0.0'
複製程式碼
2. 初始化、配置、構建
在Application的onCreate中進行初始化、配置、構建。 務必按順序執行這三步。
2.1 初始化
DevRing.init(this);
複製程式碼
2.2 配置
根據你的需求進行相關模組的全域性配置,下面將對每個配置方法進行說明。
2.2.1 配置網路請求模組
DevRing.configureHttp()
//設定BaseUrl
.setBaseUrl(UrlConstants.BASE_URL)
//設定請求超時時長,單位秒
.setConnectTimeout(15)
//設定全域性的header資訊
.setMapHeader(mapHeader)
//設定是否啟用快取,預設不啟用
.setIsUseCache(true)
//設定快取地址,傳入的file需為資料夾,預設儲存在/storage/emulated/0/Android/data/com.xxx.xxx/cache/retrofit_http_cache下
.setCacheFolder(file)
//設定快取大小,單位byte,預設20M
.setCacheSize(size)
//設定有網路時快取保留時長,單位秒,預設60秒
.setCacheTimeWithNet(time)
//設定無網路時快取保留時長,單位秒,預設一週
.setCacheTimeWithoutNet(time)
//設定是否開啟失敗重試功能,目前僅支援普通的網路請求,上傳下載不支援。預設不開啟
.setIsUseRetryWhenError(true)
//設定失敗後重試的最大次數,預設3次
.setMaxRetryCount(2)
//設定失敗後重試的延遲時長,單位秒,預設3秒
.setTimeRetryDelay(5)
//設定是否開啟Log,預設不開啟
.setIsUseLog(true);
複製程式碼
如果以上的配置無法滿足你的要求,那麼可以通過以下方法獲取相關Builder進行具體定製
//獲取OkHttpClient.Builder
DevRing.configureHttp().getOkHttpClientBuilder();
//獲取Retrofit.Builder
DevRing.configureHttp().getRetrofitBuilder();
複製程式碼
2.2.2 配置圖片載入模組
DevRing.configureImage()
//設定“載入中”狀態時顯示的圖片
.setLoadingResId(R.mipmap.ic_image_load)
//設定“載入失敗”狀態時顯示的圖片
.setErrorResId(R.mipmap.ic_image_load)
//設定是否開啟狀態切換時的過渡動畫,預設false
.setIsShowTransition(true)
//設定是否使用okhttp3作為網路元件,預設true
.setIsUseOkhttp(false)
//設定記憶體快取大小,不建議設定,使用框架預設設定的大小即可
.setMemoryCacheSize(size)
//設定Bitmap池大小,設定記憶體快取大小的話一般這個要一起設定,不建議設定,使用框架預設設定的大小即可
.setBitmapPoolSize(size)
//設定具體的磁碟快取地址,傳入的file需為資料夾
.setDiskCacheFile(file)
//設定磁碟快取大小,單位byte,預設250M
.setDiskCacheSize(200*1024*1024)
//設定磁碟快取地址是否在外部儲存中,預設false
.setIsDiskCacheExternal(true);
複製程式碼
如果你需要替換預設實現的圖片框架(Glide),那麼
- 建立圖片管理者類,要求實現IImageManager介面
- 通過DevRing.configureImage(IImageManager)方法傳入圖片管理者類
- 傳入後和上面一樣可以進行相關配置。
DevRing.configureImage(new FrescoManager())
.setXXX()
...
.setXXXX();
複製程式碼
具體可檢視Demo,演示瞭如何使用Fresco替換Glide
替換為Fresco後,相關的ImageView需換成SimpleDraweeView。
2.2.3 配置事件匯流排模組
DevRing.configureBus()//配置預設的EventBus
//設定用於加速的Index
.setIndex(new MyEventBusIndex())
//設定是否使用index進行加速
.setIsUseIndex(true);
複製程式碼
如果你需要替換預設實現的事件匯流排框架(EventBus),那麼
- 建立事件匯流排管理者類,要求實現IBusManager介面
- 通過DevRing.configureBus(IBusManager)方法傳入事件匯流排管理者類
DevRing.configureBus(new RxBusManager());
複製程式碼
具體可檢視Demo,演示瞭如何使用RxBus替換EventBus
2.2.4 配置資料庫模組
由於GreenDao的特殊性以及具體資料表的不確定,無法很好地整合到DevRing當中。
所以需要進行如下操作:
- 建立資料庫管理者類,要求實現IDBManager介面
- 通過DevRing.configureDB(IDBManager)方法傳入資料庫管理者。
(DevRing中已提供了GreenDao的一些輔助類,所以建立起來不會複雜,具體過程請參考Demo)
DevRing.configureDB(new GreenDBManager());
複製程式碼
使用其他資料庫也同樣是通過DevRing.configureDB(IDBManager)方法傳入資料庫管理者。 Demo中演示瞭如何使用原生的資料庫替換GreenDao
DevRing.configureDB(new NativeDBManager());
複製程式碼
2.2.5 配置快取模組
DevRing.configureCache()
//設定磁碟快取最大快取大小,單位為byte,預設無上限
.setDiskCacheMaxSize(50*1024*1024)
//設定磁碟快取的資料夾數量上限,預設無上限
.setDiskCacheMaxCount(10)
//配置磁碟快取的地址,傳入的File需為資料夾,預設儲存在/data/user/0/com.xxx.xxx/cache下
.setDiskCacheFolder(file);
複製程式碼
2.2.6 配置其他模組
DevRing.configureOther()
//設定是否開啟崩潰日誌功能,預設不開啟
.setIsUseCrashDiary(true)
//設定崩潰日誌的地址,傳入的file需為資料夾,預設儲存在/storage/emulated/0/Android/data/com.xxx.xxx/cache/crash_log下
.setCrashDiaryFolder(file)
//設定是否顯示Ringlog列印的內容,預設true
.setIsShowRingLog(true);
複製程式碼
2.3 構建
DevRing.create();
複製程式碼
3. 開始呼叫
幾大模組都是通過DevRing.xxxManager()得到管理者,然後進行具體操作。
3.1 網路請求模組
3.1.1 獲取Retrofit的請求API介面
DevRing.httpManager().getService(XXXApiService.class);
複製程式碼
3.1.2 普通請求
DevRing.httpManager().commonRequest(observable, new CommonObserver<HttpResult<List<MovieRes>>>() {
@Override
public void onResult(HttpResult<List<MovieRes>> result) {
}
@Override
public void onError(int errType, String errMessage) {
}
}, RxLifecycleUtil.bindUntilEvent(lifeEmitter, FragmentEvent.DESTROY));
複製程式碼
呼叫commonRequest()方法發起普通請求
- 引數1為普通的網路請求Observable。
- 引數2為請求回撥Observer。
- 庫中提供了CommonObserver,對異常資訊進行了包裝。
- 引數3為控制生命週期的LifecycleTransformer。
- 可通過RxLifecycleUtil來獲取與頁面生命週期繫結的LifecycleTransformer。
- 例如傳入RxLifecycleUtil.bindUntilEvent(lifeEmitter, FragmentEvent.DESTROY)),則表示該請求會在Fragment Destroy時銷燬。
- 傳入null 則表示不對該請求進行生命週期控制
3.1.3 上傳請求,可監聽進度
DevRing.httpManager().uploadRequest(observable, new UploadObserver(UrlConstants.UPLOAD) {
@Override
public void onResult(Object result) {
}
@Override
public void onError(long progressInfoId, String errMessage) {
}
@Override
public void onProgress(ProgressInfo progressInfo) {
}
}, RxLifecycleUtil.bindUntilDestroy(lifeEmitter));
複製程式碼
呼叫uploadRequest()方法發起上傳請求
- 引數1為上傳的網路請求Observable。
- 引數2為上傳的請求回撥UploadObserver,可用於監聽上傳進度。
- 如果不需要監聽上傳進度,則使用空的建構函式
- 如果是普通地監聽某個上傳的進度,則使用一個引數的建構函式,並傳入上傳的URL地址
- 如果是使用同一個URL但根據請求引數的不同而上傳不同資源的情況,則使用兩個引數的建構函式,第一個引數傳入上傳的URL地址,第二引數傳入自定義的字串加以區分。
- onProgress(ProgressInfo progressInfo) 中獲取進度資訊
- onError(long progressInfoId, String errMessage) 中的progressInfoId為0,則為請求相關的異常,如果不為0,則為上傳讀寫過程的異常
- 引數3為控制生命週期的LifecycleTransformer。 3.1.2中已作了說明
3.1.4 下載請求,可監聽進度
DevRing.httpManager().downloadRequest(file, observable, new DownloadObserver(UrlConstants.DOWNLOAD) {
@Override
public void onResult(boolean isSaveSuccess, String filePath) {
}
@Override
public void onError(long progressInfoId, String errMessage) {
}
@Override
public void onProgress(ProgressInfo progressInfo) {
}
}, RxLifecycleUtil.bindUntilDestroy(lifeEmitter));
複製程式碼
呼叫downloadRequest()方法發起下載請求
- 引數1為目標儲存檔案,下載的內容將儲存於此。
- 引數2為下載的網路請求Observable。
- 引數3為下載的請求回撥DownloadObserver,可用於監聽下載進度。
- 如果不需要監聽下載進度,則使用空的建構函式
- 如果是普通地監聽某個下載的進度,則使用一個引數的建構函式,並傳入下載的URL地址
- 如果是使用同一個URL但根據請求引數的不同而下載不同資源的情況,則使用兩個引數的建構函式,第一個引數傳入下載的URL地址,第二引數傳入自定義的字串加以區分。
- onResult(boolean isSaveSuccess, String filePath) 中的isSaveSuccess表示是否成功儲存到目標檔案中,filePath為目標檔案的絕對路徑。
- onProgress(ProgressInfo progressInfo) 中獲取進度資訊
- onError(long progressInfoId, String errMessage) 中的progressInfoId為0,則為請求相關的異常,如果不為0,則為下載讀寫過程的異常
- 引數4為控制生命週期的LifecycleTransformer。 3.1.2中已作了說明
3.2 圖片請求模組
3.2.1 普通載入圖片
DevRing.imageManager().loadNet(url, imageView); //載入網路圖片到控制元件
DevRing.imageManager().loadRes(resId, imageView);//載入res資源圖片到控制元件
DevRing.imageManager().loadAsset(assetName, imageView);//載入asset資源圖片到控制元件
DevRing.imageManager().loadFile(file, imageView);//載入本地圖片檔案到控制元件
複製程式碼
- 將自動使用 2.2.2 配置的“載入中顯示的圖片”,“載入失敗顯示的圖片”,“是否開啟過渡效果” 來進行載入。
3.2.2 定製化載入圖片
相比3.2.1,多了一個LoadOption引數,用於設定載入選項。
//載入圖片,並應用圓角、模糊、灰白效果。
DevRing.imageManager().loadNet/loadRes/loadAsset/loadFile(url, imageView,
new LoadOption().setRoundRadius(80).setIsGray(true).setBlurRadius(5));
複製程式碼
LoadOption目前支援設定
- 載入中狀態顯示的圖片
- 載入失敗狀態顯示的圖片
- 是否開啟狀態切換時的過渡動畫
- 是否載入為圓形圖片
- 載入為圓角圖片的圓角值
- 載入為模糊圖片的模糊值
- 是否載入為灰白圖片
3.2.3 預載入圖片
DevRing.imageManager().preLoad(url);
複製程式碼
3.2.4 獲取網路圖片的Bitmap
DevRing.imageManager().getBitmap(context, url, new ImageListener<Bitmap>(){
@Override
public void onSuccess(Bitmap result) {
//獲取成功,回撥在主執行緒
}
@Override
public void onFail(Throwable throwable) {
//獲取失敗,回撥在主執行緒
}
});
複製程式碼
3.2.5 下載圖片到指定檔案
DevRing.imageManager().downLoadImage(context, url, file, new ImageListener<File>(){
@Override
public void onSuccess(File result) {
//下載成功,回撥在後臺執行緒
}
@Override
public void onFail(Throwable throwable) {
//下載失敗,回撥在後臺執行緒
}
});
複製程式碼
3.2.6 清空記憶體快取
DevRing.imageManager().clearMemoryCache();
複製程式碼
3.2.7 清空磁碟快取
DevRing.imageManager().clearDiskCache();
複製程式碼
3.2.8 呼叫介面以外的方法
如果圖片管理者中定義了IImageManager介面以外的方法,可以通過傳入具體型別來呼叫。
DevRing.<GlideManager>imageManager().xxx();
複製程式碼
3.3 事件匯流排模組
3.3.1 訂閱
DevRing.busManager().register(subscriber);
複製程式碼
3.3.2 接觸訂閱
DevRing.busManager().unregister(subscriber);
複製程式碼
3.3.3 傳送普通事件
DevRing.busManager().postEvent(event);
複製程式碼
3.3.4 傳送粘性事件
DevRing.busManager().postStickyEvent(event);
複製程式碼
3.3.5 呼叫介面以外的方法
如果事件匯流排管理者中定義了IBusManager介面以外的方法,可以通過傳入具體型別來呼叫。
DevRing.<EventBusManager>busManager().cancelDelivery(event);
複製程式碼
3.4 資料庫模組
需先在DBManager的putTableManager()方法中,將資料表管理者通過(kye,value)方式放進Map中。
對key值對應的資料表,進行增刪改查等。
3.4.1 增
DevRing.tableManager(key).insertOne(object); //插入一個資料
DevRing.tableManager(key).insertSome(list); //插入多個資料
DevRing.tableManager(key).insertOrReplaceOne(object); //插入一個資料,如果已存在則進行替換,根據主鍵來判斷是否已存在
DevRing.tableManager(key).insertOrReplaceSome(list); //插入多個資料,如果已存在則進行替換,根據主鍵來判斷是否已存在
複製程式碼
3.4.2 刪
DevRing.tableManager(key).deleteOne(object); //刪除一個資料
DevRing.tableManager(key).deleteSome(list); //刪除多個資料
DevRing.tableManager(key).deleteOneByKey(primarykey); //根據主鍵刪除一個資料
DevRing.tableManager(key).deleteSomeByKeys(listPrimarykey); //根據主鍵刪除多個資料
DevRing.tableManager(key).deleteAll(); //刪除表中所有資料
複製程式碼
3.4.3 改
DevRing.tableManager(key).updateOne(object); //更新一個資料
DevRing.tableManager(key).updateSome(list); //更新多個資料
複製程式碼
3.4.4 查
DevRing.tableManager(key).loadOne(primarykey); //根據主鍵獲取一個資料
DevRing.tableManager(key).loadAll(); //獲取全部資料
DevRing.tableManager(key).count(); //獲取表資料的數量
DevRing.tableManager(key).rawQuery(sql, selectionArgs); //條件查詢
複製程式碼
3.4.5 執行SQL語句
DevRing.tableManager(key).execSQL(sql); //執行SQL語句
複製程式碼
3.4.6 呼叫介面以外的方法
如果表管理者中定義了ITableManager介面以外的方法,可以通過傳入具體型別來呼叫。
DevRing.<GreenTableManager>tableManager().queryBuilder().list();
複製程式碼
3.5 快取模組
3.5.1 記憶體快取
DevRing.cacheManager().memoryCache().put(key, object); //存入資料
DevRing.cacheManager().memoryCache().get(key); //取出資料
DevRing.cacheManager().memoryCache().remove(key); //移除資料
DevRing.cacheManager().memoryCache().contains(key); //是否包key值對應的資料
DevRing.cacheManager().memoryCache().clear(); //清空所有資料
複製程式碼
3.5.2 磁碟快取,可指定快取時長
DevRing.cacheManager().diskCache(name).put(key, object); //存入資料
DevRing.cacheManager().diskCache(name).put(key, object, saveTime); //存入資料,並指定快取時長
DevRing.cacheManager().diskCache(name).getXXX(key); //取出資料
DevRing.cacheManager().diskCache(name).remove(key); //移除資料
DevRing.cacheManager().diskCache(name).getCacheCount(); //獲取已快取的數量
DevRing.cacheManager().diskCache(name).getCacheSize(); //獲取已快取的空間大小
DevRing.cacheManager().diskCache(name).clear(); //清空所有資料
複製程式碼
3.5.3 SharedPreference
DevRing.cacheManager().spCache(name).put(key, object); //存入資料
DevRing.cacheManager().spCache(name).getXXX(key); //取出資料
DevRing.cacheManager().spCache(name).getAll(); //取出全部資料
DevRing.cacheManager().spCache(name).remove(key); //移除資料
DevRing.cacheManager().spCache(name).clear(); //清空所有資料
複製程式碼
3.6 許可權管理模組
DevRing.permissionManager().requestEachCombined(activity, new PermissionListener() {
@Override
public void onGranted(String permissionName) {
//如果全部許可權都被授予
}
@Override
public void onDenied(String permissionName) {
//如果使用者拒絕了其中一個授權請求
}
@Override
public void onDeniedWithNeverAsk(String permissionName) {
//如果使用者拒絕了其中一個授權請求,且勾選了不再提醒,則需要引導使用者到許可權管理頁面開啟
}
}, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA);
複製程式碼
- 還提供了一個requestEach()方法,引數都一樣。
- 如果要求申請的許可權全都授予才能使用某功能的話,建議使用requestEachCombined()方法來申請。
3.7 Activity棧模組
DevRing.activityStackManager().pushOneActivity(activity); //存進一個activity
DevRing.activityStackManager().popOneActivity(activity); //彈出棧頂的activity
DevRing.activityStackManager().currentActivity(); //獲取棧頂的activity
DevRing.activityStackManager().firstActivity(); //獲取棧底(第一個壓住棧)的activity
DevRing.activityStackManager().getStackSize(); //獲取應用activity的數量
DevRing.activityStackManager().exitActivity(activity); //退出activity
DevRing.activityStackManager().exitActivity(class); //退出型別為cls的Activity
DevRing.activityStackManager().exitActivityFirstIn(class); //退出型別為class且第一個進棧的Activity
DevRing.activityStackManager().exitActivityLastIn(class); //退出型別為class且最後一個進棧的Activity
DevRing.activityStackManager().exitAllActivityExceptThis(class); //退出除class型別以外的所有Activity
DevRing.activityStackManager().exitApplication() //退出應用(所有activity)
複製程式碼
3.8 LifeCycleCallback
提供了ActivityLifeCallback 和 FragmentLifeCallback,以實現基類的功能。
只需Activity實現IBaseActivity介面即可完成相關的基類操作。
只需Fragment實現IBaseFragment介面即可完成相關的基類操作。
具體請檢視關於基類的那些事 以及專案程式碼
3.9 工具類
3.9.1 RingLog
可定位輸出位置的Log
RingLog.e(TAG, message); //比如列印Error級日誌
RingLog.json(TAG, jsonString);//將jsonString格式化後列印出來
RingLog.xml(TAG, xmlString);//將xmlString格式化後列印出來
...
複製程式碼
3.9.2 RingToast
吐司工具類
RingToast.show("hello world");
RingToast.show(R.string.appName);
複製程式碼
3.9.3 ColorBar
狀態列/導航欄顏色工具類
用於沉浸式狀態列實現.
來自github.com/Zackratos/U…,具體用法到裡面查閱。
3.9.4 FileUtil
檔案工具類
FileUtil.isSDCardAvailable(); //SD卡是否能用
FileUtil.getDirectory(parentDirectory, directory); //獲取資料夾
FileUtil.getFile(parentDirectory, name); //獲取檔案
FileUtil.getFile(filePath); //獲取檔案
FileUtil.deleteFile(file); //刪除檔案
FileUtil.calculateFileSize(file); //計算檔案大小
FileUtil.copyFile(source, target); //複製檔案
FileUtil.saveFile(inputStream, outputStream); //儲存檔案
複製程式碼
....更多方法請檢視程式碼
3.9.5 ImageUitl
圖片工具類.
用於對圖片進行壓縮(比例壓縮 / 質量壓縮)、跳轉到相機/相簿、對Bitmap做高斯模糊處理等。
ImageUtil.scaleCompress(res/filePath/bitmap, width, height); //按比例壓縮,返回bitmap
ImageUtil.qualityCompress(bitmap, maxSize); //質量壓縮,直至圖片不大於maxSize
ImageUtil.saveBitmapToFile(bitmap, file); //儲存圖片到檔案
複製程式碼
....更多方法請檢視程式碼
3.9.6 RxLifecycleUtil
獲取用於管理生命週期的Transformer
//獲取與Fragment生命週期繫結的LifecycleTransformer
RxLifecycleUtil.bindUntilEvent(object, FragmentEvent.XXX);
//獲取與Activity生命週期繫結的LifecycleTransformer
RxLifecycleUtil.bindUntilEvent(object, ActivityEvent.XXX);
//獲取該Activity用於控制網路請求生命週期的PublishSubject,key為Activity的記憶體地址
RxLifecycleUtil.getActivityLifeSubject(key);
//獲取該Fragment用於控制網路請求生命週期的PublishSubject,key為Fragment的記憶體地址
RxLifecycleUtil.getFragmentLifeSubject(key);
複製程式碼
3.9.7 NetworkUtil
網路狀態工具類
NetworkUtil.isNetWorkAvailable(context); //當前網路是否可用
NetworkUtil.getNetWorkType(context); //獲取當前網路型別
NetworkUtil.isWifiConnected(context); //當前是否為WIFI連線
NetworkUtil.isMobileConnected(context); //當前是否為行動網路
NetworkUtil.getAPNType(context); //獲取apn型別
複製程式碼
注意事項
- DevRing庫中AndroidManifest已新增了網路許可權,所以主專案不必重複新增。
- DevRing庫中已新增了Dagger2,Retrofit2,RxJava2,RxAndroid2,RxLifeCycle2,RxPermission2的依賴,所以主專案不必重複新增。
- 配置引數為File時,請自行確保對傳入的file具有可讀寫許可權,如果沒有需先進行許可權申請。
- 部分框架需忽略混淆,具體的混淆配置請參考Demo中app下的proguard-rules.pro檔案。