-
要構(gòu)建項(xiàng)目有送,最先我們需要的是導(dǎo)入包
com.squareup.retrofit2:retrofit:2.3.0' com.squareup.retrofit2:converter-gson:2.3.0 compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0 io.reactivex.rxjava2:rxjava:2.1.3 io.reactivex.rxjava2:rxandroid:2.0.1 com.squareup.okhttp3:logging-interceptor:3.8.1
-
然后我們需要在Andoridmanifest中添加權(quán)限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-
我們編寫一個(gè)請求接口堰汉,例如:
@GET("mmdb/movie/v3/list/hot.json") Observable<HotMovieListBean> getHostList(@Query("limit") int limit);
-
我們編寫一個(gè)Retrofit的網(wǎng)絡(luò)請求類 RetrofitClient
1.該類一共分為五部:
- 類的構(gòu)造函數(shù),初始化Retrofit完成其基本的配置
-
retrofit = new Retrofit.Builder()
.baseUrl(mBaseUrl)
.client(okHttpClient != null?okHttpClient:new OkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
-返回值為Retrofit的靜態(tài)方法initClient_BaseUrl,用來配置自定義的OkHttpClient
—public static RetrofitClient initClient_BaseUrl (OkHttpClient okHttpClient, @NonNull String baseUrl){ mBaseUrl = baseUrl; if(mInstance == null){ synchronized (RetrofitClient.class){ if(mInstance == null){ mInstance = new RetrofitClient(okHttpClient,baseUrl); } } } return mInstance; }
-
獲取經(jīng)過實(shí)例化的Retrofit的類getInstance()
public static RetrofitClient getInstance(){ if(mBaseUrl == null){ throw new RuntimeException("Please initialize Your \"BaseUrl\" in Application before use"); } if(mInstance == null){ throw new RuntimeException("Please initialize Your \"RetrofitCoreClient\" in Application before use"); } return mInstance; }
-
構(gòu)建請求接口 create(Class<T> clz)
public <T> T create(Class<T> clz){ return retrofit.create(clz); }
-
Api數(shù)據(jù)匹配
public Api api(){ return getInstance().create(Api.class); }
-
2 值得注意的是我們在配置自定義的OkHttpClient時(shí)资昧,需要在Application的onCreate中進(jìn)行配置
RetrofitClient.initClient_BaseUr
(OkHttpManager.getInstance(), Api.BASE_URL);3我們需要去編寫我們自定義的OkHttpManager
-
public class OkHttpManager {
private static OkHttpClient okHttpClient;public static OkHttpClient getInstance() {
if (okHttpClient == null) {
synchronized (OkHttpManager.class) {
if (okHttpClient == null) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
builder.addInterceptor(interceptor);
}
GlobalParameterInterceptor globalParameterInterceptor = new GlobalParameterInterceptor();
builder.addInterceptor(globalParameterInterceptor);
//超時(shí)時(shí)間
builder.connectTimeout(15, TimeUnit.SECONDS);//15S連接超時(shí)
builder.readTimeout(20, TimeUnit.SECONDS);//20s讀取超時(shí)
builder.writeTimeout(20, TimeUnit.SECONDS);//20s寫入超時(shí)
//錯(cuò)誤重連
builder.retryOnConnectionFailure(true);
okHttpClient = builder.build();
}
}
}
return okHttpClient;
}
}
以及
public class GlobalParameterInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request oldRequest = chain.request();
// 添加新的參數(shù)
HttpUrl.Builder newBuilder = oldRequest.url()
.newBuilder()
.scheme(oldRequest.url().scheme())
.host(oldRequest.url().host());
Request.Builder builder = oldRequest.newBuilder()
.method(oldRequest.method(), oldRequest.body());
//全部添加ci請求參數(shù),ci為所在地參數(shù)
int ci = SPUtils.getInstance(BaseApplication.getInstance(), Constants.SP_CITY).getInt(Constants.CITY_CODE, 20);
newBuilder.addQueryParameter("ci", String.valueOf(ci));
// 新的請求
Request newRequest = builder.url(newBuilder.build()).build();
Response response = chain.proceed(newRequest);
return response;
}
}
4 在具體的項(xiàng)目中核芽,我們需要去請求數(shù)據(jù)耘斩,值得注意的時(shí)我們在獲取上拉刷新數(shù)據(jù)時(shí)顺少,我們需要對(duì)這些數(shù)據(jù)進(jìn)行一些特別的處理,由于我們解析得到的數(shù)據(jù)就具有兩個(gè)不同的實(shí)體倦始,但是唐門之間存在聯(lián)系斗遏,所以我們我們需要先使用flatMap將兩個(gè)類轉(zhuǎn)換一下之間的數(shù)據(jù)類型,并返回一個(gè)Observable對(duì)象鞋邑,然后在使用map方法見這個(gè)實(shí)體中我們需要使用到的數(shù)據(jù)進(jìn)行轉(zhuǎn)換诵次,代碼如下:
-
public Observable<List<HotMovieListBean.DataBean.HotBean>> getMoreMovieList(final int headline, final String movieIds) {
return Observable.create(new ObservableOnSubscribe<List<HotMovieListBean.DataBean.HotBean>>() {
@Override
public void subscribe(final ObservableEmitter<List<HotMovieListBean.DataBean.HotBean>> e) throws Exception {
RetrofitClient
.getInstance()
.api()
.getHotMovieList( headline, movieIds)
.flatMap(new Function<HotMovieListBean, ObservableSource<HotMovieListBean.DataBean.MoviesBean>>() {
@Override
public ObservableSource<HotMovieListBean.DataBean.MoviesBean> apply(@NonNull HotMovieListBean hotMovieListBean) throws Exception {
if (hotMovieListBean.getData().getMovies().size() > 0) {
return Observable.fromIterable(hotMovieListBean.getData().getMovies());
}
return Observable.error(new Exception("沒有更多數(shù)據(jù)"));
}
})
//map操作符將數(shù)據(jù)轉(zhuǎn)換為需要的數(shù)據(jù)
.map(new Function<HotMovieListBean.DataBean.MoviesBean, HotMovieListBean.DataBean.HotBean>() {
@Override
public HotMovieListBean.DataBean.HotBean apply(@NonNull HotMovieListBean.DataBean.MoviesBean moviesBean) throws Exception {
HotMovieListBean.DataBean.HotBean hotBean = new HotMovieListBean.DataBean.HotBean();
hotBean.setBoxInfo(moviesBean.getBoxInfo());
hotBean.setCat(moviesBean.getCat());
hotBean.setCivilPubSt(moviesBean.getCivilPubSt());
hotBean.setId(moviesBean.getId());
hotBean.setShowInfo(moviesBean.getShowInfo());//播放場次
hotBean.setSc(moviesBean.getSc());//得分
hotBean.setNm(moviesBean.getNm());//片名
hotBean.setVer(moviesBean.getVer());//3D標(biāo)簽
hotBean.setScm(moviesBean.getScm());//描述
hotBean.setPreSale(moviesBean.getPreSale());//是否預(yù)售
hotBean.setWish(moviesBean.getWish());//期待觀影人數(shù)
hotBean.setImg(moviesBean.getImg());
return hotBean;
}
})
.toList()
.subscribe(new Consumer<List<HotMovieListBean.DataBean.HotBean>>() {
@Override
public void accept(@NonNull List<HotMovieListBean.DataBean.HotBean> hotBeen) throws Exception {
e.onNext(hotBeen);
e.onComplete();
}
}, new Consumer<Throwable>() {
@Override
public void accept(@NonNull Throwable throwable) throws Exception {
e.onError(throwable);
}
});
}
});}
} 5 我們在HotMovieListPresenter中將數(shù)據(jù)添加到容器中并為其轉(zhuǎn)換線程
-
addSubcribeUntilDestory(hotMovieListManager.getHotMovieList(limit)
.compose(SchedulersCompat.<HotMovieListBean>applyIoSchedulers())
.subscribe(new Consumer<HotMovieListBean>() {
@Override
public void accept(@NonNull HotMovieListBean hotMovieListBean) throws Exception {
mView.addMovieIds(hotMovieListBean.getData().getMovieIds());
mView.addHotMovieList(hotMovieListBean.getData().getHot());
}
}, new Consumer<Throwable>() {
@Override
public void accept(@NonNull Throwable throwable) throws Exception {
Logger.e(throwable.getMessage());
mView.showError(ErrorHanding.handleError(throwable));} }, new Action() { @Override public void run() throws Exception { mView.showContent(); } }));
線程的轉(zhuǎn)換類
public class SchedulersCompat {
public static <T>ObservableTransformer<T,T> applyIoSchedulers(){
return new ObservableTransformer<T, T>() {
@Override
public ObservableSource<T> apply(@NonNull Observable<T> upstream) {
return upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
};
}
}