【移動應(yīng)用開發(fā)技術(shù)】RxJava+Retrofit+OkHttp網(wǎng)絡(luò)請求的示例分析_第1頁
【移動應(yīng)用開發(fā)技術(shù)】RxJava+Retrofit+OkHttp網(wǎng)絡(luò)請求的示例分析_第2頁
【移動應(yīng)用開發(fā)技術(shù)】RxJava+Retrofit+OkHttp網(wǎng)絡(luò)請求的示例分析_第3頁
【移動應(yīng)用開發(fā)技術(shù)】RxJava+Retrofit+OkHttp網(wǎng)絡(luò)請求的示例分析_第4頁
【移動應(yīng)用開發(fā)技術(shù)】RxJava+Retrofit+OkHttp網(wǎng)絡(luò)請求的示例分析_第5頁
已閱讀5頁,還剩22頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論