![【移動應(yīng)用開發(fā)技術(shù)】RxJava+Retrofit+OkHttp網(wǎng)絡(luò)請求的示例分析_第1頁](http://file4.renrendoc.com/view/18fd32a9eb087fed7f8f033448c9581e/18fd32a9eb087fed7f8f033448c9581e1.gif)
![【移動應(yīng)用開發(fā)技術(shù)】RxJava+Retrofit+OkHttp網(wǎng)絡(luò)請求的示例分析_第2頁](http://file4.renrendoc.com/view/18fd32a9eb087fed7f8f033448c9581e/18fd32a9eb087fed7f8f033448c9581e2.gif)
![【移動應(yīng)用開發(fā)技術(shù)】RxJava+Retrofit+OkHttp網(wǎng)絡(luò)請求的示例分析_第3頁](http://file4.renrendoc.com/view/18fd32a9eb087fed7f8f033448c9581e/18fd32a9eb087fed7f8f033448c9581e3.gif)
![【移動應(yīng)用開發(fā)技術(shù)】RxJava+Retrofit+OkHttp網(wǎng)絡(luò)請求的示例分析_第4頁](http://file4.renrendoc.com/view/18fd32a9eb087fed7f8f033448c9581e/18fd32a9eb087fed7f8f033448c9581e4.gif)
![【移動應(yīng)用開發(fā)技術(shù)】RxJava+Retrofit+OkHttp網(wǎng)絡(luò)請求的示例分析_第5頁](http://file4.renrendoc.com/view/18fd32a9eb087fed7f8f033448c9581e/18fd32a9eb087fed7f8f033448c9581e5.gif)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】RxJava+Retrofit+OkHttp網(wǎng)絡(luò)請求的示例分析
簡介:封裝成果/upload/information/20200623/125/125583.gif//
完美封裝簡化版
private
void
simpleDo()
{
SubjectPost
postEntity
=
new
SubjectPost(simpleOnNextListener,this);
postEntity.setAll(true);
HttpManager
manager
=
HttpManager.getInstance();
manager.doHttpDeal(postEntity);
}
//
回調(diào)一一對應(yīng)
HttpOnNextListener
simpleOnNextListener
=
new
HttpOnNextListener<List<Subject>>()
{
@Override
public
void
onNext(List<Subject>
subjects)
{
tvMsg.setText("已封裝:\n"
+
subjects.toString());
}
/*用戶主動調(diào)用,默認是不需要覆寫該方法*/
@Override
public
void
onError(Throwable
e)
{
super.onError(e);
tvMsg.setText("失?。篭n"
+
e.toString());
}
};/**
*
Retrofit加入rxjava實現(xiàn)http請求
*/
private
void
onButton9Click()
{
//手動創(chuàng)建一個OkHttpClient并設(shè)置超時時間
okhttp3.OkHttpClient.Builder
builder
=
new
OkHttpClient.Builder();
builder.connectTimeout(5,
TimeUnit.SECONDS);
Retrofit
retrofit
=
new
Retrofit.Builder()
.client(builder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(HttpManager.BASE_URL)
.build();
/
加載框
final
ProgressDialog
pd
=
new
ProgressDialog(this);
HttpService
apiService
=
retrofit.create(HttpService.class);
Observable<RetrofitEntity>
observable
=
apiService.getAllVedioBy(true);
observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(
new
Subscriber<RetrofitEntity>()
{
@Override
public
void
onCompleted()
{
if
(pd
!=
null
&&
pd.isShowing())
{
pd.dismiss();
}
}
@Override
public
void
onError(Throwable
e)
{
if
(pd
!=
null
&&
pd.isShowing())
{
pd.dismiss();
}
}
@Override
public
void
onNext(RetrofitEntity
retrofitEntity)
{
tvMsg.setText("無封裝:\n"
+
retrofitEntity.getData().toString());
}
@Override
public
void
onStart()
{
super.onStart();
pd.show();
}
}
);
}/upload/information/20200623/125/125584.pngRetrofit<uses-permission
android:name="android.permission.INTERNET"/>
/*rx-android-java*/
compile
'com.squareup.retrofit2:adapter-rxjava:2.1.0'
compile
'com.trello:rxlifecycle:1.0'
compile
'com.trello:rxlifecycle-components:1.0'
/*rotrofit*/
compile
'com.squareup.retrofit2:retrofit:2.1.0'
compile
'com.squareup.retrofit2:converter-gson:2.0.0'
compile
'com.google.code.gson:gson:2.8.0'ReTrofit基本使用:/**
*
@api
videoLink
50音圖視頻鏈接
*
@url
/Api/AppFiftyToneGraph/videoLink
*
@method
post
*
@param
once_no
bool(選填,ture無鏈接)
一次性獲取下載地址
*
@return
json
array(
*
ret:1成功,2失敗
*
msg:信息
*
data:{
*
name:視頻名稱
*
title:標題
*
}
)String
BASE_URL
=
"
/Api/"
Retrofit
retrofit
=
new
Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();/**
*
接口地址
*
Created
by
WZG
on
2016/7/16.
*/
public
interface
MyApiEndpointInterface
{
@POST("AppFiftyToneGraph/videoLink")
Call<RetrofitEntity>
getAllVedio(@Body
boolean
once_no)
}MyApiEndpointInterface
apiService
=
retrofit.create(MyApiEndpointInterface.class);
Call<RetrofitEntity>
call
=
apiService.getAllVedio(true);
call.enqueue(new
Callback<RetrofitEntity>()
{
@Override
public
void
onResponse(Response<RetrofitEntity>
response,
Retrofit
retrofit)
{
RetrofitEntity
entity
=
response.body();
Log.i("tag",
"onResponse>"
+
entity.getMsg());
}
@Override
public
void
onFailure(Throwable
t)
{
Log.i("tag",
"onFailure>"
+
t.toString());
}
});ReTrofit+Rxjava基本使用@POST("AppFiftyToneGraph/videoLink")
Observable<RetrofitEntity>
getAllVedioBy(@Body
boolean
once_no);Retrofit
retrofit
=
new
Retrofit.Builder()
.client(builder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(HttpManager.BASE_URL)
.build();HttpService
apiService
=
retrofit.create(HttpService.class);
Observable<RetrofitEntity>
observable
=
apiService.getAllVedioBy(true);
observable.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
.subscribe(
new
Subscriber<RetrofitEntity>()
{
@Override
public
void
onCompleted()
{
}
@Override
public
void
onError(Throwable
e)
{
}
@Override
public
void
onNext(RetrofitEntity
retrofitEntity)
{
tvMsg.setText("無封裝:\n"
+
retrofitEntity.getData().toString());
}
}
);ReTrofit+Rxjava進階封裝之路/upload/information/20200623/125/125585.png請求數(shù)據(jù)封裝1.參數(shù)public
abstract
class
BaseApi<T>
implements
Func1<BaseResultEntity<T>,
T>
{
//rx生命周期管理
private
SoftReference<RxAppCompatActivity>
rxAppCompatActivity;
/*回調(diào)*/
private
SoftReference<HttpOnNextListener>
listener;
/*是否能取消加載框*/
private
boolean
cancel;
/*是否顯示加載框*/
private
boolean
showProgress;
/*是否需要緩存處理*/
private
boolean
cache;
/*基礎(chǔ)url*/
private
String
baseUrl="/Api/";
/*方法-如果需要緩存必須設(shè)置這個參數(shù);不需要不用設(shè)置*/
private
String
mothed;
/*超時時間-默認6秒*/
private
int
connectionTime
=
6;
/*有網(wǎng)情況下的本地緩存時間默認60秒*/
private
int
cookieNetWorkTime=60;
/*無網(wǎng)絡(luò)的情況下本地緩存時間默認30天*/
private
int
cookieNoNetWorkTime=24*60*60*30;
}
/**
*
設(shè)置參數(shù)
*
*
@param
retrofit
*
@return
*/
public
abstract
Observable
getObservable(Retrofit
retrofit);public
class
SubjectPostApi
extends
BaseApi
{
xxxxxxx
xxxxxxx
@Override
public
Observable
getObservable(Retrofit
retrofit)
{
HttpPostService
service
=
retrofit.create(HttpPostService.class);
return
service.getAllVedioBys(isAll());
}
}Func1<BaseResultEntity<T>,
T>,后邊結(jié)合結(jié)果處理鏈接起來使用
@Override
public
T
call(BaseResultEntity<T>
httpResult)
{
if
(httpResult.getRet()
==
0)
{
throw
new
HttpTimeException(httpResult.getMsg());
}
return
httpResult.getData();
}
*
ret:1成功,2失敗
*
msg:信息
*
data:{
*
name:視頻名稱
*
title:標題
*
}/**
*
回調(diào)信息統(tǒng)一封裝類
*
Created
by
WZG
on
2016/7/16.
*/
public
class
BaseResultEntity<T>
{
//
判斷標示
private
int
ret;
//
提示信息
private
String
msg;
//顯示數(shù)據(jù)(用戶需要關(guān)心的數(shù)據(jù))
private
T
data;
xxxxx
get-set
xxxxx
}public
interface
HttpPostService
{
@POST("AppFiftyToneGraph/videoLink")
Call<RetrofitEntity>
getAllVedio(@Body
boolean
once_no);
}操作類封裝
private
volatile
static
HttpManager
INSTANCE;
//構(gòu)造方法私有
private
HttpManager()
{
}
//獲取單例
public
static
HttpManager
getInstance()
{
if
(INSTANCE
==
null)
{
synchronized
(HttpManager.class)
{
if
(INSTANCE
==
null)
{
INSTANCE
=
new
HttpManager();
}
}
}
return
INSTANCE;
}
/**
*
處理http請求
*
*
@param
basePar
封裝的請求數(shù)據(jù)
*/
public
void
doHttpDeal(BaseApi
basePar)
{
//手動創(chuàng)建一個OkHttpClient并設(shè)置超時時間緩存等設(shè)置
OkHttpClient.Builder
builder
=
new
OkHttpClient.Builder();
builder.connectTimeout(basePar.getConnectionTime(),
TimeUnit.SECONDS);
builder.addInterceptor(new
CookieInterceptor(basePar.isCache()));
/*創(chuàng)建retrofit對象*/
Retrofit
retrofit
=
new
Retrofit.Builder()
.client(builder.build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.baseUrl(basePar.getBaseUrl())
.build();
/*rx處理*/
ProgressSubscriber
subscriber
=
new
ProgressSubscriber(basePar);
Observable
observable
=
basePar.getObservable(retrofit)
/*失敗后的retry配置*/
.retryWhen(new
RetryWhenNetworkException())
/*生命周期管理*/
.compose(basePar.getRxAppCompatActivity().bindToLifecycle())
/*http請求線程*/
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
/*回調(diào)線程*/
.observeOn(AndroidSchedulers.mainThread())
/*結(jié)果判斷*/
.map(basePar);
/*數(shù)據(jù)回調(diào)*/
observable.subscribe(subscriber);
}ProgressSubscriber封裝/**
*
用于在Http請求開始時,自動顯示一個ProgressDialog
*
在Http請求結(jié)束是,關(guān)閉ProgressDialog
*
調(diào)用者自己對請求數(shù)據(jù)進行處理
*
Created
by
WZG
on
2016/7/16.
*/
public
class
ProgressSubscriber<T>
extends
Subscriber<T>
{
/*是否彈框*/
private
boolean
showPorgress
=
true;
/*
軟引用回調(diào)接口*/
private
SoftReference<HttpOnNextListener>
mSubscriberOnNextListener;
/*軟引用反正內(nèi)存泄露*/
private
SoftReference<RxAppCompatActivity>
mActivity;
/*加載框可自己定義*/
private
ProgressDialog
pd;
/*請求數(shù)據(jù)*/
private
BaseApi
api;
/**
*
構(gòu)造
*
*
@param
api
*/
public
ProgressSubscriber(BaseApi
api)
{
this.api
=
api;
this.mSubscriberOnNextListener
=
api.getListener();
this.mActivity
=
new
SoftReference<>(api.getRxAppCompatActivity());
setShowPorgress(api.isShowProgress());
if
(api.isShowProgress())
{
initProgressDialog(api.isCancel());
}
}
/**
*
初始化加載框
*/
private
void
initProgressDialog(boolean
cancel)
{
Context
context
=
mActivity.get();
if
(pd
==
null
&&
context
!=
null)
{
pd
=
new
ProgressDialog(context);
pd.setCancelable(cancel);
if
(cancel)
{
pd.setOnCancelListener(new
DialogInterface.OnCancelListener()
{
@Override
public
void
onCancel(DialogInterface
dialogInterface)
{
onCancelProgress();
}
});
}
}
}
/**
*
顯示加載框
*/
private
void
showProgressDialog()
{
if
(!isShowPorgress())
return;
Context
context
=
mActivity.get();
if
(pd
==
null
||
context
==
null)
return;
if
(!pd.isShowing())
{
pd.show();
}
}
/**
*
隱藏
*/
private
void
dismissProgressDialog()
{
if
(!isShowPorgress())
return;
if
(pd
!=
null
&&
pd.isShowing())
{
pd.dismiss();
}
}
}
/**
*
訂閱開始時調(diào)用
*
顯示ProgressDialog
*/
@Override
public
void
onStart()
{
showProgressDialog();
/*緩存并且有網(wǎng)*/
if
(api.isCache()
&&
AppUtil.isNetworkAvailable(RxRetrofitApp.getApplication()))
{
/*獲取緩存數(shù)據(jù)*/
CookieResulte
cookieResulte
=
CookieDbUtil.getInstance().queryCookieBy(api.getUrl());
if
(cookieResulte
!=
null)
{
long
time
=
(System.currentTimeMillis()
-
cookieResulte.getTime())
/
1000;
if
(time
<
api.getCookieNetWorkTime())
{
if
(mSubscriberOnNextListener.get()
!=
null)
{
mSubscriberOnNextListener.get().onCacheNext(cookieResulte.getResulte());
}
onCompleted();
unsubscribe();
}
}
}
}
/**
*
完成,隱藏ProgressDialog
*/
@Override
public
void
onCompleted()
{
dismissProgressDialog();
}/**
*
對錯誤進行統(tǒng)一處理
*
隱藏ProgressDialog
*
*
@param
e
*/
@Override
public
void
onError(Throwable
e)
{
dismissProgressDialog();
/*需要緩存并且本地有緩存才返回*/
if
(api.isCache())
{
Observable.just(api.getUrl()).subscribe(new
Subscriber<String>()
{
@Override
public
void
onCompleted()
{
}
@Override
public
void
onError(Throwable
e)
{
errorDo(e);
}
@Override
public
void
onNext(String
s)
{
/*獲取緩存數(shù)據(jù)*/
CookieResulte
cookieResulte
=
CookieDbUtil.getInstance().queryCookieBy(s);
if
(cookieResulte
==
null)
{
throw
new
HttpTimeException("網(wǎng)絡(luò)錯誤");
}
long
time
=
(System.currentTimeMillis()
-
cookieResulte.getTime())
/
1000;
if
(time
<
api.getCookieNoNetWorkTime())
{
if
(mSubscriberOnNextListener.get()
!=
null)
{
mSubscriberOnNextListener.get().onCacheNext(cookieResulte.getResulte());
}
}
else
{
CookieDbUtil.getInstance().deleteCookie(cookieResulte);
throw
new
HttpTimeException("網(wǎng)絡(luò)錯誤");
}
}
});
}
else
{
errorDo(e);
}
}
/*錯誤統(tǒng)一處理*/
private
void
errorDo(Throwable
e)
{
Context
context
=
mActivity.get();
if
(context
==
null)
return;
if
(e
instanceof
SocketTimeoutException)
{
Toast.makeText(context,
"網(wǎng)絡(luò)中斷,請檢查您的網(wǎng)絡(luò)狀態(tài)",
Toast.LENGTH_SHORT).show();
}
else
if
(e
instanceof
ConnectException)
{
Toast.makeText(context,
"網(wǎng)絡(luò)中斷,請檢查您的網(wǎng)絡(luò)狀態(tài)",
Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(context,
"錯誤"
+
e.getMessage(),
Toast.LENGTH_SHORT).show();
}
if
(mSubscriberOnNextListener.get()
!=
null)
{
mSubscriberOnNextListener.get().onError(e);
}
}
/**
*
將onNext方法中的返回結(jié)果交給Activity或Fragment自己處理
*
*
@param
t
創(chuàng)建Subscriber時的泛型類型
*/
@Override
public
void
onNext(T
t)
{
if
(mSubscriberOnNextListener.get()
!=
null)
{
mSubscriberOnNextListener.get().onNext(t);
}
}/**
*
成功回調(diào)處理
*
Created
by
WZG
on
2016/7/16.
*/
public
abstract
class
HttpOnNextListener<T>
{
/**
*
成功后回調(diào)方法
*
@param
t
*/
public
abstract
void
onNext(T
t);
/**
*
緩存回調(diào)結(jié)果
*
@param
string
*/
public
void
onCacheNext(String
string){
}
/**
*
失敗或者錯誤方法
*
主動調(diào)用,更加靈活
*
@param
e
*/
public
void
onError(Throwable
e){
}
/**
*
取消回調(diào)
*/
public
void
onCancel(){
}
}失敗后的retry處理OkHttpClient.Builder
builder
=
new
OkHttpClient.Builder();
builder.retryOnConnectionFailure(true);
/**
*
retry條件
*
Created
by
WZG
on
2016/10/17.
*/
public
class
RetryWhenNetworkException
implements
Func1<Observable<?
extends
Throwable>,
Observable<?>>
{
//
retry次數(shù)
private
int
count
=
3;
//
延遲
private
long
delay
=
3000;
//
疊加延遲
private
long
increaseDelay
=
3000;
public
RetryWhenNetworkException()
{
}
public
RetryWhenNetworkException(int
count,
long
delay)
{
this.count
=
count;
this.delay
=
delay;
}
public
RetryWhenNetworkException(int
count,
long
delay,
long
increaseDelay)
{
this.count
=
count;
this.delay
=
delay;
this.increaseDelay
=
increaseDelay;
}
@Override
public
Observable<?>
call(Observable<?
extends
Throwable>
observable)
{
return
observable
.zipWith(Observable.range(1,
count
+
1),
new
Func2<Throwable,
Integer,
Wrapper>()
{
@Override
public
Wrapper
call(Throwable
throwable,
Integer
integer)
{
return
new
Wrapper(throwable,
integer);
}
}).flatMap(new
Func1<Wrapper,
Observable<?>>()
{
@Override
public
Observable<?>
call(Wrapper
wrapper)
{
if
((wrapper.throwable
instanceof
ConnectException
||
wrapper.throwable
instanceof
SocketTimeoutException
||
wrapper.throwable
instanceof
TimeoutException)
&&
wrapper.index
<
count
+
1)
{
//如果超出重試次數(shù)也拋出錯誤,否則默認是會進入onCompleted
return
Observable.timer(delay
+
(wrapper.index
-
1)
*
increaseDelay,
TimeUnit.MILLISECONDS);
}
return
Observable.error(wrapper.throwable);
}
});
}
private
class
Wrapper
{
private
int
index;
private
Throwable
throwable;
public
Wrapper(Throwable
throwable,
int
index)
{
this.index
=
index;
this.throwable
=
throwable;
}
}
}使用api接口對象/**
*
測試數(shù)據(jù)
*
Created
by
WZG
on
2016/7/16.
*/
public
class
SubjectPostApi
extends
BaseApi
{
//
接口需要傳入的參數(shù)
可自定義不同類型
private
boolean
all;
/*任何你先要傳遞的參數(shù)*/
//
String
xxxxx;
/**
*
默認初始化需要給定回調(diào)和rx周期類
*
可以額外設(shè)置請求設(shè)置加載框顯示,回調(diào)等(可擴展)
*
@param
listener
*
@param
rxAppCompatActivity
*/
public
SubjectPostApi(HttpOnNextListener
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024民間借貸合同范本(28篇)
- 2025年農(nóng)村子女撫養(yǎng)費用分擔(dān)協(xié)議
- 2025年供電企業(yè)與用戶用電合作協(xié)議
- 2025年共同策劃健身房合作合同書
- 企業(yè)勞動合同協(xié)議2025年
- 2025年企業(yè)員工勞動合同補充協(xié)議范本
- 2025年鋁合金預(yù)拉伸厚板和蒙皮鋁合金板項目立項申請報告模范
- 2025年高性能陶瓷復(fù)合材料項目立項申請報告模板
- 2025年企業(yè)變更代理協(xié)議
- 2025年漲緊輪項目提案報告模板
- 港口自動化與智慧港口發(fā)展方向
- 人教版小學(xué)英語單詞表(完整版)
- 飛灰處置及資源化綜合利用項目可行性研究報告模板-備案拿地
- 2024年咨詢工程師考試大綱
- 免疫治療皮疹護理查房
- 2024年棉柔巾行業(yè)市場趨勢分析
- 黑龍江省哈爾濱市雙城區(qū)2024年八年級下冊物理期末經(jīng)典試題含解析
- 老年期譫妄課件
- 項目采購管理培訓(xùn)
- 河道保潔服務(wù)日常巡邏方案及措施
- 《工業(yè)氣體泄漏氣云紅外成像檢測系統(tǒng)的性能評價技術(shù)規(guī)范》 征求意見稿
評論
0/150
提交評論