-
要构建项目,最先我们需要的是导入包
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中添加权限
<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" />
-
我们编写一个请求接口,例如:
@GET("mmdb/movie/v3/list/hot.json") Observable<HotMovieListBean> getHostList(@Query("limit") int limit);
-
我们编写一个Retrofit的网络请求类 RetrofitClient
1.该类一共分为五部:
- 类的构造函数,初始化Retrofit完成其基本的配置
-
retrofit = new Retrofit.Builder()
.baseUrl(mBaseUrl)
.client(okHttpClient != null?okHttpClient:new OkHttpClient())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
-返回值为Retrofit的静态方法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; }
-
获取经过实例化的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; }
-
构建请求接口 create(Class<T> clz)
public <T> T create(Class<T> clz){ return retrofit.create(clz); }
-
Api数据匹配
public Api api(){ return getInstance().create(Api.class); }
-
2 值得注意的是我们在配置自定义的OkHttpClient时,需要在Application的onCreate中进行配置
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);
//超时时间
builder.connectTimeout(15, TimeUnit.SECONDS);//15S连接超时
builder.readTimeout(20, TimeUnit.SECONDS);//20s读取超时
builder.writeTimeout(20, TimeUnit.SECONDS);//20s写入超时
//错误重连
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();
// 添加新的参数
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请求参数,ci为所在地参数
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 在具体的项目中,我们需要去请求数据,值得注意的时我们在获取上拉刷新数据时,我们需要对这些数据进行一些特别的处理,由于我们解析得到的数据就具有两个不同的实体,但是唐门之间存在联系,所以我们我们需要先使用flatMap将两个类转换一下之间的数据类型,并返回一个Observable对象,然后在使用map方法见这个实体中我们需要使用到的数据进行转换,代码如下:
-
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("没有更多数据"));
}
})
//map操作符将数据转换为需要的数据
.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标签
hotBean.setScm(moviesBean.getScm());//描述
hotBean.setPreSale(moviesBean.getPreSale());//是否预售
hotBean.setWish(moviesBean.getWish());//期待观影人数
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中将数据添加到容器中并为其转换线程
-
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(); } }));
线程的转换类
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());
}
};
}
}