文章目錄
HttpManager
描述
這是一個封裝了Http網絡請求、HTTP多接口合併、網絡文件下載的庫。改編自wzgiceman的RxRetrofit庫。
Github地址:https://github.com/wkxjc/HttpManager
效果圖
下載
第一步. 在根目錄的build.gradle中添加以下代碼:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
第二步. 添加gradle依賴
implementation 'com.github.wkxjc:HttpManager:1.7'
如何使用?
1.單個網絡請求:
private val httpManager by lazy { HttpManager(this) }
...
httpManager.request(randomWallpaperApi, object : HttpListener() {
override fun onNext(result: String) {
tvResult.text = result
}
override fun onError(error: Throwable) {
tvResult.text = error.message
}
})
2.多個網絡請求:
private val httpManager by lazy { HttpManager(this) }
...
httpManager.request(
apis = arrayOf(randomWallpaperApi, categoryApi),
listener = object : HttpListListener() {
/**
* 單個api結果回調
*/
override fun onSingleNext(api: BaseApi, result: String): Any {
when (api) {
randomWallpaperApi -> {
Log.d("HttpListActivity", "收到單個結果:randomWallpaperApi:$result")
// 這裏可以將返回的字符串轉換爲任意對象,一般在這裏使用Gson/fastJson解析對象
return 123
}
categoryApi -> Log.d("HttpListActivity", "收到單個結果:categoryApi:$result")
}
return super.onSingleNext(api, result)
}
/**
* 所有api結果回調
*/
override fun onNext(resultMap: HashMap<BaseApi, Any>) {
// 通過 as 方法,將resultMap中保存的對象取出並轉換成onSingleNext返回的類型
tvResultList.text =
"randomWallpaperApi result: ${resultMap[randomWallpaperApi] as Int}\n" +
"categoryApi result: ${resultMap[categoryApi].toString()}"
}
override fun onError(error: Throwable) {
tvResultList.text = error.message
}
}
)
3.下載網絡文件:
HttpDownManager.down(DownConfig().apply {
url = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
})
配置
使用HttpManager進行單個api請求或多個api請求之前,你需要一些準備工作.
第一步. 新建ApiConfig,繼承自DefaultApiConfig,重寫baseUrl變量:
class ApiConfig : DefaultApiConfig() {
override var baseUrl = "你的網絡請求BaseUrl"
}
第二步. 在Application中初始化RxRetrofitApp,設置apiConfig:
RxRetrofitApp.apply {
application = this@MyApplication
apiConfig = ApiConfig()
}
第三步. 和使用Retrofit庫類似,新建ApiService,例如:
interface WallpaperApiService {
@GET("v1/vertical/vertical")
fun getRandomWallpaper(
@Query("limit") limit: Int = 30,
@Query("skip") skip: Int = 0,
@Query("adult") adult: Boolean = false,
@Query("first") first: Int = 0,
@Query("order") order: String = "hot"
): Observable<String>
}
新建Api,繼承自BaseApi,例如:
class RandomWallpaperApi : BaseApi() {
override fun getObservable(): Observable<String> {
val apiService = retrofit.create(WallpaperApiService::class.java)
return apiService.getRandomWallpaper()
}
}
OK,這樣就能獲取到接口請求結果了。
使用HttpDownManager進行網絡文件下載之前,只需要確保在Application中初始化了RxRetrofitApp的application即可。
RxRetrofitApp.apply {
application = this@MyApplication
}
返回結果統一解析
在實際開發中,後臺接口返回的數據一般是有統一格式的,例如本Demo中接口返回的數據統一格式如下:
class BaseResult {
// 此變量爲0表示請求成功
var code: Int = 0
// 請求失敗時,此變量攜帶錯誤信息
var msg: String = ""
// 此變量存儲返回的業務數據
var res: String = ""
}
在此框架中,我們可以將返回數據先統一按此結構解析,僅將返回的業務數據傳到業務層。新建ResultConverter:
class ResultConverter : IResultConverter {
override fun convert(response: String): String {
// 在這裏對結果統一解析
val result = JSONObject.parseObject(response, BaseResult::class.java)
// 通過定義的錯誤碼,統一做錯誤處理
if (result.code != 0) throw Throwable("code != 0, msg = ${result.msg}")
return result.res
}
}
然後在Application中設置即可:
RxRetrofitApp.apply {
...
resultConverter = ResultConverter()
}
在api中可以通過ignoreResultConverter配置關閉這一層解析
Http返回碼統一處理
有時候,後臺並不會通過BaseResult結構的errorMessage返回錯誤信息,而是通過Http請求的"404"或者"403"等等錯誤碼告知前端請求錯誤。
在此框架中,我們可以將Http返回碼統一處理。新建HttpResponseProcessor:
class HttpResponseProcessor : IHttpResponseProcessor {
override fun handleResponse(response: Response): Response {
// 在這裏可以處理http返回的錯誤碼:response.code(),這裏的錯誤碼不同於BaseResult中的errorCode
if (response.code() >= 400) throw Throwable("Http response code = ${response.code()}")
return response
}
}
然後在Application中設置即可:
RxRetrofitApp.apply {
...
httpResponseProcessor = HttpResponseProcessor()
}
定製
1.全局修改網絡請求默認配置
在ApiConfig中,不僅可以配置baseUrl,還可以配置以下參數,以下是默認值:
open class DefaultApiConfig {
// Retrofit網絡請求的BaseUrl
open var baseUrl = ""
// 是否顯示Loading彈窗
open var showLoading = true
// Loading彈窗是否可取消
open var loadingCancelable = true
// 緩存配置
open var cacheConfig = CacheConfig().apply {
// 是否需要緩存處理
cache = false
// 有網的時候的緩存過期時間
onlineCacheTime = 30
// 沒網的時候的緩存過期時間
offlineCacheTime = 60 * 60 * 24 * 30
}
// 是否忽略ResultConverter解析
open var ignoreResultConverter: Boolean = false
// 重試配置
open var retry = RetryConfig().apply {
// 重試次數
count = 5
// 重試延遲時間
delay = 100L
// 每次增加延遲的時間
increaseDelay = 500L
}
// 超時時間配置
open var timeOutConfig = TimeoutConfig().apply {
// 連接超時時間
connectionTime = 10L
// 讀取超時時間
readTime = 10L
// 寫入超時時間
writeTime = 10L
}
// Http請求head信息
open var headers: Headers? = null
}
在這裏的配置是對所有的網絡請求生效的。
2.單個網絡請求修改默認配置
單個網絡請求可配置參數與全局網絡請求可配置參數相同。使用示例:
class RandomWallpaperApi : BaseApi() {
init {
// Retrofit網絡請求的BaseUrl
baseUrl = "單獨配置baseUrl"
// 是否顯示Loading彈窗
showLoading = true
// Loading彈窗是否可取消
loadingCancelable = true
// 緩存配置
cacheConfig = CacheConfig().apply {
// 是否需要緩存處理
cache = false
// 有網的時候的緩存過期時間
onlineCacheTime = 30
// 沒網的時候的緩存過期時間
offlineCacheTime = 60 * 60 * 24 * 30
}
// 是否忽略ResultConverter解析
ignoreResultConverter = false
// 重試配置
retry = RetryConfig().apply {
// 重試次數
count = 5
// 重試延遲時間
delay = 100L
// 每次增加延遲的時間
increaseDelay = 500L
}
// 超時時間配置
timeOutConfig = TimeoutConfig().apply {
// 連接超時時間
connectionTime = 10L
// 讀取超時時間
readTime = 10L
// 寫入超時時間
writeTime = 10L
}
// Http請求head信息,示例如下:
headers = Headers.of(mapOf("name1" to "value1", "name2" to "value2"))
}
override fun getObservable(): Observable<String> {
val apiService = retrofit.create(WallpaperApiService::class.java)
return apiService.getRandomWallpaper()
}
}
3.Http多接口合併請求全局配置
Http多接口合併請求時,單個api配置的參數大多數仍然生效,只有showLoading、loadingCancelable兩個參數不再生效,需要單獨配置。
多接口合併可配置參數如下,以下是默認值:
open class DefaultHttpListConfig {
// 是否顯示Loading彈窗
open var showLoading: Boolean = true
// Loading彈窗是否可取消
open var loadingCancelable: Boolean = true
// 是否按照順序請求api
open var order: Boolean = false
}
如果需要全局修改Http多接口請求的配置,新建HttpListConfig類,繼承自DefaultHttpListConfig:
class HttpListConfig : DefaultHttpListConfig() {
override var showLoading = true
override var loadingCancelable = true
override var order = false
}
然後在Application中設置即可:
RxRetrofitApp.apply {
...
httpListConfig = HttpListConfig()
}
4.Http多接口合併請求單獨配置
單獨配置與全局配置的可配置參數相同。使用示例:
httpManager.request(
apis = apis,
config = HttpListConfig(showLoading = true, loadingCancelable = true, order = false),
listener = listener
)
5.Http下載文件全局配置
下載文件時,全局默認配置如下:
open class DefaultDownConfig {
/**保存的文件夾路徑,如果不設置,默認路徑是"應用緩存路徑/download/",如果設置爲外部路徑,需要自己確保有讀寫權限*/
var saveDir: String = ""
get() {
if (field.isNotEmpty()) return field
val cacheDir = RxRetrofitApp.application.externalCacheDir.absolutePath
?: throw Throwable("application is null")
return "$cacheDir/download/"
}
/**下載進度更新頻率,即下載多少B之後更新一次,默認4K。使用[PROGRESS_BY_PERCENT]表示按百分比更新*/
var progressStep = 1024 * 4
/**重試配置*/
var retry = RetryConfig()
/**head信息*/
var headers: Headers? = null
}
如果需要修改全局配置,新建DownConfig類,繼承自DefaultDownConfig類:
class DownConfig :DefaultDownConfig(){
/**保存的文件夾路徑,如果不設置,默認路徑是"應用緩存路徑/download/",如果設置爲外部路徑,需要自己確保有讀寫權限*/
override var saveDir: String = ""
get() {
if (field.isNotEmpty()) return field
val cacheDir = RxRetrofitApp.application.externalCacheDir?.absolutePath
?: throw Throwable("application is null")
return "$cacheDir/download/"
}
/**下載進度更新頻率,即下載多少B之後更新一次,默認4K。使用[PROGRESS_BY_PERCENT]表示按百分比更新*/
override var progressStep = 1024 * 4
/**重試配置*/
override var retry = RetryConfig()
/**head信息*/
override var headers: Headers? = null
}
然後在Application中設置即可:
RxRetrofitApp.apply {
...
downConfig = DownConfig()
}
6.Http下載文件單獨配置
單獨配置與全局配置的可配置參數相同。使用示例:
HttpDownManager.down(DownConfig().apply {
url = "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"
saveDir = "${RxRetrofitApp.application.externalCacheDir?.absolutePath}/download/"
/**保存的文件名字,如果不設置,默認名字是url的最後一段*/
saveFileName = "big_buck_bunny.mp4"
/**下載進度更新頻率,即下載多少B之後更新一次,使用[PROGRESS_BY_PERCENT]表示按百分比更新*/
/**進度更新頻率,下載多少Byte後更新一次進度。默認每下載4KB更新一次,使用[DownConfig.PROGRESS_BY_PERCENT]表示每下載百分之一更新一次*/
progressStep = 1024 * 128
/**重試配置*/
retry = RetryConfig()
/**head信息*/
headers = Headers.of(mapOf("name1" to "value1", "name2" to "value2"))
})
Bug 反饋
如果您有任何反饋或建議,歡迎提交到 Github issues。或者給我留言、交流。