




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rè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)用,默認(rèn)是不需要覆寫該方法*/
@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:標(biāo)題
*
}
)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進(jìn)階封裝之路/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;
/*超時時間-默認(rèn)6秒*/
private
int
connectionTime
=
6;
/*有網(wǎng)情況下的本地緩存時間默認(rèn)60秒*/
private
int
cookieNetWorkTime=60;
/*無網(wǎng)絡(luò)的情況下本地緩存時間默認(rèn)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:標(biāo)題
*
}/**
*
回調(diào)信息統(tǒng)一封裝類
*
Created
by
WZG
on
2016/7/16.
*/
public
class
BaseResultEntity<T>
{
//
判斷標(biāo)示
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ù)進(jìn)行處理
*
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();
}/**
*
對錯誤進(jìn)行統(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ù)也拋出錯誤,否則默認(rèn)是會進(jìn)入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;
/**
*
默認(rèn)初始化需要給定回調(diào)和rx周期類
*
可以額外設(shè)置請求設(shè)置加載框顯示,回調(diào)等(可擴(kuò)展)
*
@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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 腳手架施工安全培訓(xùn)內(nèi)容與現(xiàn)場實際操作匹配性研究考核試卷
- 納米復(fù)合材料在地鐵制造中的應(yīng)用考核試卷
- 合作伙伴關(guān)系生命周期管理考核試卷
- 產(chǎn)業(yè)政策扶持力度分析考核試卷
- 設(shè)備集成化對生產(chǎn)流程的影響考核試卷
- 農(nóng)用工具批發(fā)行業(yè)競爭格局演變考核試卷
- 供應(yīng)鏈戰(zhàn)略聯(lián)盟知識管理實踐分析考核試卷
- 2025年中國PVC-U加筋管數(shù)據(jù)監(jiān)測報告
- 2025年中國PE封口膜袋數(shù)據(jù)監(jiān)測研究報告
- 2025年中國LED不銹鋼節(jié)能電筒數(shù)據(jù)監(jiān)測報告
- 醫(yī)共體醫(yī)保管理工作制度
- 顧問銷售培訓(xùn)課件
- 儲量知識考試題及答案
- 成都市住宅工程質(zhì)量常見問題防治措施
- 2025年經(jīng)濟(jì)學(xué)基礎(chǔ)知識測試試題及答案
- 2025年7月浙江省普通高中學(xué)業(yè)水平考試押題模擬暨選考意向?qū)б須v史學(xué)科試題(原卷版)
- 貴州省黔西南州、黔東南州、黔南州2025年八年級英語第二學(xué)期期末學(xué)業(yè)水平測試試題含答案
- 杭州市公安局濱江區(qū)分局招聘警務(wù)輔助人員筆試真題2024
- 2025年江蘇省高考物理試卷真題(含答案)
- DB31/ 638-2012鑄鋼件單位產(chǎn)品能源消耗限額
- 腎腫瘤超聲診斷
評論
0/150
提交評論