Android开发项目中关于Retrofit2.0+RxJava+OkHttp的封装和使用

释放双眼,带上耳机,听听看~!

1.引入依赖库

在app的 build.gradle文件中添加如下配置:

    //下面两个是RxJava 和RxAndroid
compile 'io.reactivex:rxandroid:1.2.1'
compile 'io.reactivex:rxjava:1.3.0'
compile 'com.squareup.retrofit2:retrofit:2.1.0'//retrofit
compile 'com.squareup.retrofit2:converter-gson:2.1.0'//转换器,请求结果转换成Model
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'//配合Rxjava 使用

2.创建retrofitUtil

package com.wy.simula.net.util;
import com.wy.simula.application.SimulationApplication;
import com.wy.simula.net.ApiService;
import com.wy.simula.net.cookies.BaseInterceptor;
import com.wy.simula.net.cookies.CookieManger;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitUtil {
private static final int DEFAULT_TIMEOUT = 5;//超时时间
private ApiService apiService;
private static RetrofitUtil instance;
private RetrofitUtil() {
Map<String, String> map = new HashMap<>();
map.put("Content-type", "application/json; charset=utf-8");
OkHttpClient.Builder client = new OkHttpClient.Builder()
.addNetworkInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.HEADERS))
.cookieJar(new CookieManger(SimulationApplication.getAppContext()))//这里可以做cookie传递,保存等操作
.addInterceptor(new BaseInterceptor(map))
.retryOnConnectionFailure(true)
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
Retrofit retrofit = new Retrofit.Builder()
.client(client.build())
.baseUrl(ApiService.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
apiService = retrofit.create(ApiService.class);
}
public ApiService getApiService() {
return apiService;
}
//采用单例模式
public static RetrofitUtil getInstance() {
if (instance == null) {
synchronized (RetrofitUtil.class) {
instance = new RetrofitUtil();
}
}
return instance;
}
}

说明:配置了接口的baseUrl和一个converter,GsonConverterFactory 是默认提供的Gson 转换器,Retrofit 也支持其他的一些转换器,详情请看官网Retrofit官网
这里是引用
这里的HttpLoggingInterceptor是okhttp3中自带的一个谷歌浏览器调试方法类。
比较简单实用。
所以这里就是将缓存控制的拦截器以及日志拦截器加到OkHttpClient.Builder中了。
将Cookie持久化也加到OkHttpClient.Builder中了。
就是要用的的方法加到这个OkHttpClient.Builder中就行了。

BaseInterceptor 类

package com.xx.xxxx.xx.cookies;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class BaseInterceptor implements Interceptor {
private Map<String, String> headers;
public BaseInterceptor(Map<String, String> headers) {
this.headers = headers;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
if (headers != null && headers.size() > 0) {
Set<String> keys = headers.keySet();
for (String headerKey : keys) {
builder.addHeader(headerKey, headers.get(headerKey)).build();
}
}
return chain.proceed(builder.build());
}
}

3.写一个接口

public interface ApiService {
String BASE_URL = "http://www.xxx.xxx.xxx/api/";
// 获取 banner轮播图
@GET("conf/getBanner")
Observable<BannerModel> getBanner(@Query("type") int type);
}

4.编写网络工具类

public class HttpUtil {
private static HttpUtil httpUtil = new HttpUtil();
private ApiService apiService;
private HttpUtil() {
apiService = RetrofitUtil.getInstance().getApiService();
}
public static HttpUtil getInstance() {
return httpUtil;
}
private <T> void toSubscribe(Subscriber<T> subscriber, Observable<T> observable) {
observable.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
}
public void getBanner(Subscriber<BannerModel> subscriber,int type) {
toSubscribe(subscriber, apiService.getBanner(type));
}
}

5.Activity中调用

BaseActivity

package com.wy.simula.base;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.KeyEvent;
import com.wy.simula.application.SimulationApplication;
import com.wy.simula.net.HttpUtil;
import com.wy.simula.util.ACache;
import com.wy.simula.util.AppSession;
import com.wy.simula.util.ToastUtil;
import com.wy.simula.util.UiUtils;
public abstract class BaseActivity extends AppCompatActivity {
protected Context mContext;
protected HttpUtil mHttpUtil;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getContentResId() != 0) {
setContentView(getContentResId());
}
mContext = this;
mHttpUtil = HttpUtil.getInstance();
init();
}
public abstract int getContentResId();
public abstract void init();
@Override
protected void onDestroy() {
super.onDestroy();
mContext = null;
}
}

MainActivity

package com.wy.simula.ui;
public class MainActivity extends BaseActivity{
@Override
public int getContentResId() {
return R.layout.activity_main;
}
@Override
public void init() {
mHttpUtil.getBanner(new ProgressSubscriber<BannerModel>(mActivity,this,false) {
@Override
public void next(BannerModel model) {
if (model.getCode().equals(Constant.SUCCESS)) {//请求成功
}
}
}
},BANNER_HOME);
}
}

6.ProgressSuscriber

package com.wy.simula.net.util;
import android.content.Context;
import android.util.Log;
import com.wy.simula.util.ToastUtil;
import com.wy.simula.widget.recyclerview.IRecyclerSwipe;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import rx.Subscriber;
public abstract class ProgressSubscriber<T> extends Subscriber<T> implements ProgressCancel {
private Context context;
private ProgressDialog handler;
private IRecyclerSwipe iRecyclerSwipe;
private boolean isHaveProgressBar=false;
public ProgressSubscriber(Context context) {
this.context = context;
isHaveProgressBar=true;
if(isHaveProgressBar){
handler = new ProgressDialog(context, this, true);
}
}
/**
* 是否有进度条
* @param context
* @param isHasProgress
*/
public ProgressSubscriber(Context context,Boolean isHasProgress) {
this.context = context;
this.isHaveProgressBar=isHasProgress;
if(isHaveProgressBar){
handler = new ProgressDialog(context, this, true);
}
}
public ProgressSubscriber(Context context, IRecyclerSwipe iRecyclerSwipe) {
this.context = context;
this.iRecyclerSwipe = iRecyclerSwipe;
isHaveProgressBar=true;
handler = new ProgressDialog(context, this,isHaveProgressBar);
}
public ProgressSubscriber(Context context, IRecyclerSwipe iRecyclerSwipe,boolean isTrue) {
this.context = context;
this.iRecyclerSwipe = iRecyclerSwipe;
isHaveProgressBar=isTrue;
handler = new ProgressDialog(context,this,isHaveProgressBar);
}
private void showProgressDialog() {
if(isHaveProgressBar){
if (handler != null) {
handler.obtainMessage(ProgressDialog.SHOW_PROGRESS_DIALOG).sendToTarget();
}
}
}
private void dismissProgressDialog() {
if(isHaveProgressBar){
if (handler != null) {
handler.obtainMessage(ProgressDialog.DISMISS_PROGRESS_DIALOG).sendToTarget();
handler = null;
}
}
}
@Override
public void onStart() {
showProgressDialog();
super.onStart();
}
@Override
public void onCompleted() {
if (iRecyclerSwipe != null) {
iRecyclerSwipe.hideSwipeLoading();
}
dismissProgressDialog();
}
@Override
public void onError(Throwable e) {
if (iRecyclerSwipe != null) {
iRecyclerSwipe.hideSwipeLoading();
//            iRecyclerSwipe.showItemFail(iRecyclerSwipe.getName() + " 列表数据获取失败!");
}
if (e instanceof SocketTimeoutException) {
ToastUtil.show(context, "网络中断,网络连接超时!");
} else if (e instanceof ConnectException) {
ToastUtil.show(context, "网络中断,请检查您的网络状态!");
} else {
//            ToastUtil.show(context, "error:" + e.getMessage());
Log.d("MyInfo","exception:"+e.getMessage());
}
dismissProgressDialog();
}
@Override
public void onNext(T t) {
next(t);
if (iRecyclerSwipe != null) {
iRecyclerSwipe.hideSwipeLoading();
}
}
@Override
public void onCancel() {
if (!this.isUnsubscribed()) {
this.unsubscribe();
}
}
public abstract void next(T t);
}

7.接口IRecyclerSwipe

package com.wy.simula.widget.recyclerview;
public interface IRecyclerSwipe {
void showItemFail(String msg);
void hideSwipeLoading();
void setNoMore();
}

8.接口返回的json数据结构 bean

package com.wy.simula.model.result;
import java.util.List;
public class BannerModel {
/**
* total : 5
* code : 1
* preUrl : https://www.spaimy.top/
* message : 查询成功。
* rows : [{"pkId":361,"url":"banner/index-banner.png","typeDes":"首页轮播图","type":"1"},{"pkId":362,"url":"banner/index-banner.png","typeDes":"首页轮播图","type":"1"},{"pkId":363,"url":"banner/index-banner.png","typeDes":"首页轮播图","type":"1"},{"pkId":364,"url":"banner/index-banner.png","typeDes":"首页轮播图","type":"1"},{"pkId":365,"url":"banner/index-banner.png","typeDes":"首页轮播图","type":"1"}]
*/
private int total;
private String code;
private String preUrl;
private String message;
private List<RowsBean> rows;
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPreUrl() {
return preUrl;
}
public void setPreUrl(String preUrl) {
this.preUrl = preUrl;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<RowsBean> getRows() {
return rows;
}
public void setRows(List<RowsBean> rows) {
this.rows = rows;
}
public static class RowsBean {
/**
* "pkId": 11198,
"url": "banner/20181112/2018111219200817420181024红包BannerPC.jpg",
"typeDes": "20181024红包BannerPC",
"type": "3",
"sort": 10,
"status": 1
*/
private int pkId;
private String url;
private String typeDes;
private String type;
private int sort;
private int status;
public int getSort() {
return sort;
}
public void setSort(int sort) {
this.sort = sort;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getPkId() {
return pkId;
}
public void setPkId(int pkId) {
this.pkId = pkId;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getTypeDes() {
return typeDes;
}
public void setTypeDes(String typeDes) {
this.typeDes = typeDes;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
}

项目源码:https://github.com/soulofandroid/RetrofitDemo

参考:RxJava结合ProgressDialog实现请求数据
Retrofit2+Rxjava2+okHttp 网络框架封装

人已赞赏
Android文章

Android开发Retrofit2+Rxjava2+okHttp 网络框架封装

2020-3-14 16:59:33

Android文章

android 决TextView中MaxLines与ellipsize=end冲突问题

2020-3-14 17:29:34

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
有新消息 消息中心
搜索