ProxyFactory的主要用途是為了簡(jiǎn)化異步任務(wù)蜡峰。可以快速酌儒、方便的使用其開(kāi)發(fā)異步相關(guān)的業(yè)務(wù)需求。
首先放上Github倉(cāng)庫(kù)地址如果你覺(jué)得喜歡或有用勺疼,還請(qǐng)一鍵三連教寂,感謝捏鱼。
下載
第一步:添加 JitPack 倉(cāng)庫(kù)到你項(xiàng)目根目錄的 gradle 文件中。
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
第二步:添加這個(gè)依賴(lài)酪耕。
dependencies {
implementation "com.github.kelinZhou:ProxyFactory:${LastVersion}"
}
使用
在使用之前需要先對(duì)其進(jìn)行初始化导梆。
ProxyFactory.init(application, ToasterImpl())
class ToasterImpl : Toaster {
/**
* 處理異步任務(wù)中捕獲的異常,如果你希望自己處理改異常則需要返回null迂烁,返回null之后Proxy的onFailed方法將不會(huì)被回調(diào)看尼,否則會(huì)將你返回的ApiException回調(diào)給Proxy的onFailed方法。
*/
override fun handError(e: Throwable): ApiException {
return e as? ApiException ?: ApiException(-10, e.message)
}
/**
* 顯示調(diào)用異步任務(wù)失敗時(shí)的提示盟步。
*/
override fun showFailedToast(e: ApiException) {
Toast.makeText(applicationContext, e.displayMessage, Toast.LENGTH_LONG).show()
}
/**
* 顯示加載中的樣式藏斩。
*/
override fun showProgress(context: Context, progressTip: String?) {
showProgressDialog(context, progressTip)
}
/**
* 隱藏加載中的樣式。
*/
override fun hideProgress(context: Context) {
dismissProgressDialog(context)
}
}
Proxy
ProxyFactory提供了以下幾類(lèi)的Proxy用于處理不同業(yè)務(wù)場(chǎng)景却盘。
1. DataProxy 只關(guān)心返回?cái)?shù)據(jù)的代理狰域。
使用DataProxy您可以方便的執(zhí)行異步任務(wù)。
ProxyFactory.createProxy { Observable.just("I'm Result!") }
.onSuccess { data ->
// Do something with data.
}
.onFailed { e ->
// Do something with Exception.
}
.request() //請(qǐng)求啟動(dòng)任務(wù)黄橘。
2.ActionDataProxy 帶有動(dòng)作的代理兆览。
使用ActionDataProxy您可以方便的執(zhí)行異步任務(wù)并關(guān)系其動(dòng)作。
ProxyFactory.createActionProxy { Observable.just("I'm Result for.") }
.onSuccess { data, action ->
// Do something with data & action.
}
.onFailed { e, action ->
// Do something with data & action.
}
.request(LoadAction.LOAD)
不同于DataProxy
塞关,ActionDataProxy
必須在發(fā)起請(qǐng)求時(shí)傳入動(dòng)作(action
)LoadAction或ActionParameter抬探,然后可以在回調(diào)中獲取到action。
3.IdDataProxy 支持請(qǐng)求參數(shù)的代理帆赢。
使用IdDataProxy您可以方便的執(zhí)行異步任務(wù)并傳遞參數(shù)小压。
ProxyFactory.createIdProxy<String, String> { id -> Observable.just("I'm Result for $id.") }
.onSuccess { id, data ->
// Do something with data & id.
}
.onFailed { id, e ->
// Do something with Exception & id.
}
.request("Kelin")
不同于DataProxy
,IdDataProxy
可以在回調(diào)中獲取到發(fā)起任務(wù)時(shí)傳入的參數(shù)椰于。
4.IdActionDataProxy 同時(shí)支持請(qǐng)求參和動(dòng)作的代理怠益。
ProxyFactory.createIdActionProxy<String, String> { id -> Observable.just("I'm Result for $id.") }
.bind(this, object :IdActionDataProxy.IdActionDataCallback<String, ActionParameter, String>{
override fun onSuccess(id: String, action: ActionParameter, data: String) {
// Do something with data & id & action.
}
override fun onFailed(id: String, action: ActionParameter, e: ApiException) {
// Do something with data & id & action.
}
})
.request(ActionParameter.createInstance(), "Kelin")
需要注意的是IdActionDataProxy不再支持onSuccess
和onFailed
的方式設(shè)置回調(diào)。
ActionParameter
動(dòng)作及功能參數(shù)廉羔,ActionParameter的核心就是LoadAction溉痢。而LoadAction
是一個(gè)枚舉類(lèi),主要成員如下:
- LOAD :沒(méi)有數(shù)據(jù)load憋他。對(duì)于分頁(yè)的孩饼,load總是第一頁(yè)的數(shù)據(jù)。
- RETRY :load失敗竹挡,retry(這個(gè)不叫refresh6迫ⅰ!>竞薄L萋搿)宝泵。對(duì)于分頁(yè)的,load總是第一頁(yè)的數(shù)據(jù)轩娶。
- REFRESH : 已經(jīng)load成功儿奶,再次load。對(duì)于分頁(yè)的鳄抒,load總是第一頁(yè)的數(shù)據(jù)闯捎。
- AUTO_REFRESH : 已經(jīng)load成功,再次load许溅。對(duì)于分頁(yè)的瓤鼻,load總是已經(jīng)加載過(guò)的所有頁(yè)。
- LOAD_MORE : 加載更多(分頁(yè)加載)贤重。
說(shuō)到分頁(yè)ActionParameter
還有個(gè)子類(lèi)PageActionParameter茬祷,PageActionParameter
可以用來(lái)處理分頁(yè)邏輯。
如果要使用分頁(yè)加載則需要用到ProxyFactory
的createPageActionProxy
方法或createPageIdActionProxy
方法并蝗,下面以createPageIdActionProxy
方法舉例:
ProxyFactory.createPageIdActionProxy<String, String> { id, pages -> Observable.just("I'm Result for $id. Pages(page:${pages.page}, size:${pages.size}).") }
.bind(this, object :IdActionDataProxy.IdActionDataCallback<String, ActionParameter, String>{
override fun onSuccess(id: String, action: ActionParameter, data: String) {
// Do something with data & id & action.
}
override fun onFailed(id: String, action: ActionParameter, e: ApiException) {
// Do something with data & id & action.
}
})
.request(PageActionParameter.createInstance(true, 20), "Kelin")
上面的栗子中PageActionParameter.createInstance(true, 20)
參數(shù)true
表示啟用分頁(yè)加載祭犯,20
表示每頁(yè)的數(shù)量。
注意事項(xiàng)
bind方法
所有的Proxy都是支持通過(guò)調(diào)用其bind
方法為其綁定到生命周期組件LifecycleOwner
的借卧,是為了防止頁(yè)面銷(xiāo)毀后任務(wù)沒(méi)有銷(xiāo)毀而回調(diào)又是內(nèi)部類(lèi)從而可能導(dǎo)致內(nèi)存泄露的問(wèn)題盹憎。
當(dāng)然,bind
方法也不是強(qiáng)制要求調(diào)用的铐刘,沒(méi)有調(diào)用過(guò)bind
方法的Proxy的回調(diào)均為一次性回調(diào)陪每,即無(wú)論是onSuccess
還是onFailed
被回調(diào)過(guò)一次后,回調(diào)就會(huì)立即從Proxy內(nèi)部被移除引用镰吵。也就意味著沒(méi)有調(diào)用過(guò)bind
方法的Proxy不能被重復(fù)使用檩禾。
下面列舉一個(gè)Proxy使用不當(dāng)?shù)睦踝樱?/em>
val proxy = ProxyFactory.createProxy { Observable.just("I'm Result!") }
.onSuccess { data ->
// Do something with data.
}
.onFailed { e ->
// Do something with Exception.
}
btnTest.setOnClickListener{
proxy.request() //請(qǐng)求啟動(dòng)任務(wù)。
}
在這個(gè)栗子中疤祭,只有btnTest
按鈕被第一次點(diǎn)擊的時(shí)候會(huì)執(zhí)行onSuccess
還是onFailed
回調(diào)盼产,而從第二次開(kāi)始以及之后的所有點(diǎn)擊都不會(huì)再執(zhí)行onSuccess
還是onFailed
回調(diào)了。
*如果想要重復(fù)使用一個(gè)Proxy則需要對(duì)上面的代碼進(jìn)行改造:
val proxy = ProxyFactory.createProxy { Observable.just("I'm Result!") }
.bind(activity) //如果是在Activity中使用則直接傳入`this`勺馆,如果是在Fragment中使用則最好傳入`viewLifecycleOwner`戏售。
.onSuccess { data ->
// Do something with data.
}
.onFailed { e ->
// Do something with Exception.
}
btnTest.setOnClickListener{
proxy.request() //請(qǐng)求啟動(dòng)任務(wù)。
}
progress方法
所有Proxy都支持在調(diào)用request
方法時(shí)自動(dòng)彈窗l(fā)oading對(duì)話(huà)框草穆。loading對(duì)話(huà)框的彈出和隱藏能力由Toaster接口中的showProgress
和hideProgress
方法提供灌灾。
下面舉個(gè)栗子來(lái)演示progress方法的用法:
ProxyFactory.createProxy { Observable.just("I'm Result!") }
.progress(context, "Please Wait...") //第一個(gè)參數(shù)為彈出對(duì)話(huà)框時(shí)所需要的上下文,第二個(gè)參數(shù)為loading對(duì)話(huà)框中需要顯示的文字悲柱。
.onSuccess { data ->
// Do something with data.
}
.onFailed { e ->
// Do something with Exception.
}
.request() //請(qǐng)求啟動(dòng)任務(wù)锋喜。
setNotToast方法
為了方便調(diào)用也為了回調(diào)更加靈活,所以onSuccess
還是onFailed
回調(diào)并不是都必須同時(shí)設(shè)置的,考慮到通常情況下onFailed
回調(diào)只是為了提示用戶(hù)嘿般,所以如果沒(méi)有設(shè)置onFailed
回調(diào)則默認(rèn)會(huì)彈出Toast提示用戶(hù)段标。彈出Toast的能力由Toaster接口中的showFailedToast
方法提供。如果你不希望在失敗時(shí)彈出Toast提示也不想設(shè)置onFailed
回調(diào)則可以使用該方法炉奴。
下面舉個(gè)栗子來(lái)演示setNotToast方法的用法:
ProxyFactory.createProxy { Observable.just("I'm Result!") }
.setNotToast() //禁止在失敗時(shí)自動(dòng)彈出Toast逼庞。
.onSuccess { data ->
// Do something with data.
}
.request() //請(qǐng)求啟動(dòng)任務(wù)。