一.Rxjava2也出来了一段时间了,这段时间项目就用了一下Rxjava2和retrofit来实现了网络封装,考虑到可能存在的不为人知的bug,广大技术宅也可以提出改进意见共同进步,博主QQ:1129126470,WeChat:ym1129126470 申请请注明来意,欢迎技术交流吐槽,转载请注明出处谢谢。
二.好了废话不多说了下面给出代码不吝赐教
1.依赖库
compile 'com.squareup.retrofit2:retrofit:2.0.0'
compile 'com.squareup.retrofit2:converter-jackson:2.0.0'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0-RC3'
compile 'io.reactivex.rxjava2:rxjava:2.0.0-RC3'
compile 'io.reactivex.rxjava2:rxandroid:2.0.0-RC1'
compile 'com.squareup.okhttp3:okhttp:3.2.0'
compile 'com.squareup.okio:okio:1.8.0'
2.ApiInterface接口封装
public interface ApiInterface{
Retrofit getRetrofit();
T getClientApi(Class cls);
}
3.网络检查
public class AppClient {
public final static boolean isNetworkReady(final Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni != null) {
return ni.isConnected();
}
return false;
}
public final static boolean isMobileConnected(final Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if ((null != ni) && ni.isConnected()) {
return ConnectivityManager.TYPE_MOBILE == ni.getType();
}
return false;
}
}
4.缓存处理
public class CacheApi implements ApiInterface {
private static Retrofit retrofit = null;
private volatile static CacheApi cacheApi;
private CacheApi() {
}
public static CacheApi getInstance() {
if (cacheApi == null) {
synchronized (CacheApi.class) {
if (cacheApi == null) {
cacheApi = new CacheApi();
}
}
}
return cacheApi;
}
@Override
public Retrofit getRetrofit() {
if (retrofit == null) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(15, TimeUnit.SECONDS);
builder.readTimeout(15, TimeUnit.SECONDS);
builder.writeTimeout(15, TimeUnit.SECONDS);
//错误重连
builder.retryOnConnectionFailure(true);
File cacheFile = new File(MvpContactApplication.getInstance().getExternalCacheDir(), "MybCache");
Cache cache = new Cache(cacheFile, 1024 * 1024 * 50);
Interceptor cacheInterceptor = chain -> {
Request request = chain.request();
if (!AppClient.isNetworkReady(MvpContactApplication.getInstance())) {
request = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build();
}
Response response = chain.proceed(request);
if (AppClient.isNetworkReady(MvpContactApplication.getInstance())) {
int maxAge = 0;
// 有网络时 设置缓存超时时间0个小时
response.newBuilder()
.header("Cache-Control", "public, max-age=" + maxAge)
//.removeHeader("")// 清除头信息,因为服务器如果不支持,会返回一些干扰信息,不清除下面无法生效
.build();
} else {
// 无网络时,设置超时为4周
int maxStale = 60 * 60 * 24 * 28;
response.newBuilder()
.header("Cache-Control", "public, only-if-cached, max-stale=" + maxStale)
//.removeHeader("nyn")
.build();
}
return response;
};
builder.cache(cache).addInterceptor(cacheInterceptor);
//以上设置结束,才能build(),不然设置白搭
OkHttpClient okHttpClient = builder.build();
retrofit = new Retrofit.Builder()
.baseUrl(Constant.BASE_URL)
.client(okHttpClient)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(StringConverterFactory.create())
.build();
}
return retrofit;
}
@Override
public T getClientApi(Class cls) {
Retrofit retrofit = getRetrofit();
return retrofit.create(cls);
}
}
5.DisposableBeanSubscriber
public abstract class DisposableBeanSubscriber extends DisposableSubscriber {
private Class cls;
private Context context;
private LoadingDialog loadingDialog;
private boolean decode;
public DisposableBeanSubscriber() {
}
public DisposableBeanSubscriber(Context context, Class cls) {
this.cls = cls;
this.context = context;
loadingDialog = new LoadingDialog(context);
showDialog();
}
public DisposableBeanSubscriber(Context context, Class cls, boolean decode) {
this.cls = cls;
this.context = context;
loadingDialog = new LoadingDialog(context);
showDialog();
this.decode = decode;
}
public void showDialog() {
loadingDialog.show();
}
public void dismissDialog() {
loadingDialog.close();
}
@Override
public void onNext(Object object) {
if (decode) {
LogUtils.e(context, "onNext: --------decode:" + object.toString());
iNext(new Gson().fromJson(CodeUtil.voteDecode(object.toString()), cls));
} else {
LogUtils.e(context, "onNext: ---------------" + object.toString());
iNext(new Gson().fromJson(object.toString(), cls));
}
}
@Override
public void onError(Throwable t) {
iError();
}
@Override
public void onComplete() {
iComplete();
}
protected abstract void iNext(T t);
protected void iError() {
Tos.t(context, Constant.CONNECT_ERROR);
dismissDialog();
}
protected void iComplete() {
dismissDialog();
}
}
6.正常的链接网络流程
public class NormalApi implements ApiInterface {
private static Retrofit retrofit = null;
private volatile static NormalApi normalApi;
private NormalApi() {
}
public static NormalApi getInstance() {
if (normalApi == null) {
synchronized (NormalApi.class) {
if (normalApi == null) {
normalApi = new NormalApi();
}
}
}
return normalApi;
}
@Override
public Retrofit getRetrofit() {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(15, TimeUnit.SECONDS);
builder.readTimeout(15, TimeUnit.SECONDS);
builder.writeTimeout(15, TimeUnit.SECONDS);
builder.retryOnConnectionFailure(true);
OkHttpClient okHttpClient = builder.build();
retrofit = new Retrofit.Builder()
.baseUrl(Constant.BASE_URL)
.client(okHttpClient)
.addConverterFactory(StringConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
return retrofit;
}
@Override
public T getClientApi(Class t) {
Retrofit retrofit = getRetrofit();
return retrofit.create(t);
}
}
7.下面借助我耿哥封装的思路封装StringConverterFactory
public class StringConverterFactory extends Converter.Factory {
public static StringConverterFactory create() {
return new StringConverterFactory();
}
private StringConverterFactory() {
}
@Override
public Converter responseBodyConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return new StringResponseBodyConverter();
}
@Override
public Converter requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return new StringRequestBodyConverter();
}
}
8.请求封装StringRequestBodyConverter
public class StringRequestBodyConverter implements Converter<String, RequestBody> {
private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
private static final Charset UTF_8 = Charset.forName("UTF-8");
StringRequestBodyConverter() {
}
@Override public RequestBody convert(String value) throws IOException {
Buffer buffer = new Buffer();
Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
writer.write(value);
writer.close();
return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
}
}
9.响应
public class StringResponseBodyConverter implements Converter<ResponseBody, String> {
@Override
public String convert(ResponseBody value) throws IOException {
try {
return value.string();
} finally {
value.close();
}
}
}
10RxBus相关(相当于EventBus时间总线)
public class RxBus {
//相当于Rxjava1.x中的Subject
private final FlowableProcessor
11.RxBusHelper的封装
public class RxBusHelper {
/**
* 发布消息
*
* @param o
*/
public static void post(Object o) {
RxBus.getDefault().post(o);
}
/**
* 接收消息,并在主线程处理
*
* @param aClass
* @param disposables 用于存放消息
* @param listener
* @param
*/
public static void doOnMainThread(Class aClass, CompositeDisposable disposables, OnEventListener listener) {
disposables.add(RxBus.getDefault().toFlowable(aClass).observeOn(AndroidSchedulers.mainThread()).subscribe(listener::onEvent, throwable -> listener.onError(new ErrorBean(ErrorCode.ERROR_CODE_RXBUS, ErrorCode.ERROR_DESC_RXBUS))));
}
public static void doOnMainThread(Class aClass, OnEventListener listener) {
RxBus.getDefault().toFlowable(aClass).observeOn(AndroidSchedulers.mainThread())
.subscribe(listener::onEvent, throwable ->
listener.onError(new ErrorBean(ErrorCode.ERROR_CODE_RXBUS, ErrorCode.ERROR_DESC_RXBUS)));
}
/**
* 接收消息,并在子线程处理
*
* @param aClass
* @param disposables
* @param listener
* @param
*/
public static void doOnChildThread(Class aClass, CompositeDisposable disposables, OnEventListener listener) {
disposables.add(RxBus.getDefault().toFlowable(aClass).subscribeOn(Schedulers.newThread()).subscribe(listener::onEvent, throwable -> listener.onError(new ErrorBean(ErrorCode.ERROR_CODE_RXBUS, ErrorCode.ERROR_DESC_RXBUS))));
}
public static void doOnChildThread(Class aClass, OnEventListener listener) {
RxBus.getDefault().toFlowable(aClass).subscribeOn(Schedulers.newThread()).subscribe(listener::onEvent, throwable -> listener.onError(new ErrorBean(ErrorCode.ERROR_CODE_RXBUS, ErrorCode.ERROR_DESC_RXBUS)));
}
public interface OnEventListener {
void onEvent(T t);
void onError(ErrorBean errorBean);
}
}
有什么指教的,请留言或者私信给我,我看到了及时回复。