Retrofit和Rxandroid一起使用也算是现在安卓开发里面比较流行的了,不知道大家平时都是怎样调用的呢?
来看一下我调用的方式
public void login() {
RetrofitHelper retrofitHelper = RetrofitHelper.getInstance();
Retrofit retrofit = retrofitHelper.getRetrofit();
Map options = new HashMap<>();
options.put("type", "8");
RequestServes requestSerives = retrofit.create(RequestServes.class);
Observable observable = requestSerives.Login(options);
retrofitHelper.sendRequest(observable, this, ServerUrlConstants.getLoginUrl(), data.class);
}
这就是一次网络请求,Retrofit已经封装到RetrofitHelper的单例模式里面,我们获取Retrofit实例,并加入我们需要添加的Map参数集合,最后建立Observable观察者,然后发起请求,是不是感觉很简单?
我们再来看一下回调接口,回调接口我写了四个方法,是根据目前我在职公司的json类型去构思的
public interface ICallBackListener {
/**
* 成功时的返回数据
*
* @param data 根据传入类去解析后返回的实体
* @param r 所有数据,包括msg,status
* @param url 通过返回url做标识,在一个页面判断多个接口的返回处理逻辑
*/
public void onSuccess(Object data,root r,String url);
public void onFaild(root r,String url);
public void onCompleted(String url);
public void onError(String url);
}
只要你在需要网络请求的界面实现这个接口就行了,或者我们在Activity的基类里面实现这个接口,每个子类界面可会自动实现这个接口
逻辑处理:这里我采用传入的Url做分别,url是唯一的,可以在一个界面的多次网络请求里分清这些请求回来的数据是哪个接口的,我们分开处理,做不同的业务逻辑
@Override
public void onSuccess(Object data, root r, String http) {
if(http.equals(ServerUrlConstants.getLoginUrl())){
data t = (data) data;
}else if(http.equals(ServerUrlConstants.getProductListUrl())){
List<data> s = (List<data>) data;
}
}
@Override
public void onFaild(root r, String http) {
if(http.equals(ServerUrlConstants.getLoginUrl())){
}else if(http.equals(ServerUrlConstants.getProductListUrl())){
}
}
@Override
public void onCompleted(String http) {
}
@Override
public void onError(String http) {
}
最后让我们来看下主要的RetrofitHelper类
public class RetrofitHelper {
private static final String BASE_URL = "http://betajuecainet.com/";
private static RetrofitHelper mRetrofitHelper;
private Retrofit mRetrofit;
private Class clazz;
private RetrofitHelper() {
int DEFAULT_TIMEOUT = 10;
OkHttpClient client = null;
try {
client = new OkHttpClient.Builder()
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.sslSocketFactory(getSSLSocketFactory()).hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
.build();
} catch (Exception e) {
e.printStackTrace();
}
mRetrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create()) // 使用RxJava作为回调适配器
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create()) // 使用Gson作为数据转换器
.client(client)
.build();
}
public static RetrofitHelper getInstance() {
if (mRetrofitHelper == null) {
synchronized (RetrofitHelper.class) {
if (mRetrofitHelper == null)
mRetrofitHelper = new RetrofitHelper();
}
}
return mRetrofitHelper;
}
public Retrofit getRetrofit() {
return mRetrofit;
}
/**
* rxandroid的形式发起网络请求,并在信息返回后通过callBackListener回调
*
* @param observable rxandroid的观察者
* @param callBackListener 回调接口
* @param url 通过返回url做标识,在一个页面判断多个接口的返回处理逻辑
* @param clazz Gson解析的类型
*/
public void sendRequest(Observable observable, final ICallBackListener callBackListener, final String url,
final Class clazz){
observable.debounce(250, TimeUnit.MILLISECONDS)//只接受短时间内的传回的第一个数据
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber() {
@Override
public void onCompleted() {
callBackListener.onCompleted(url);
}
@Override
public void onError(Throwable e) {
callBackListener.onError(url);
}
@Override
public void onNext(root t) {
if(t.getStatus()==1){
Gson gson = new Gson();
//如果数据是集合,通过解析成传入的类型解析,并封装成一个List
if (t.getData().isJsonArray()) {
JsonArray array = t.getData().getAsJsonArray();
List result = new ArrayList();
for (int i = 0; i < array.size(); i++) {
result.add(gson.fromJson(array.get(i), clazz));
}
callBackListener.onSuccess(result, t, url);
} else if (t.getData().isJsonObject()) {
//如果数据是json对象
callBackListener.onSuccess(gson.fromJson(t.getData(), clazz),t,url);
} else if (t.getData().isJsonPrimitive()) {
//如果数据是基本类型
callBackListener.onSuccess(gson.fromJson(t.getData(), clazz),t,url);
} else {
callBackListener.onSuccess(null,t,url);
}
}else{
callBackListener.onFaild(t,url);
}
}
});
}
public static SSLSocketFactory getSSLSocketFactory() throws Exception {
//创建一个不验证证书链的证书信任管理器。
final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
}};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts,
new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
return sslContext
.getSocketFactory();
}
}
我们知道Retrofit是基于okhttp封装的,我在RetrofitHelper的构造方法里面创建了一个OkHttpClient,设置了超时时间,证书认证,目前是不验证证书,所有https请求都通过的,如果你公司需要有证书导入,你可以在getSSLSocketFactory方法里面去修改,RetrofitHelper我做成了单例模式,避免产生不必要的实体对象,sendRequest方法是发送网络请求的主体,通过rxandroid的观察者模式设置接受第一段传回的数据,防止有多次点击button多次网络请求并返回多次数据的情况,在订阅者里面处理观察者返回的数据,onNext(root t)这里的t是此次请求所有的数据返回,通过getStatus是否等于1来判断请求是否成功,否则调用callBackListener.onFaild回调方法,root里面的data是数据主体,如果他是集合类型,我通过传入的泛型解析并封装到集合中返回,如果是对象或java基本类型直接解析返回
root这个javabean代码
public class root implements Serializable{
private String info;
private int status;
private String version;
public void setInfo(String info){
this.info = info;
}
public String getInfo(){
return this.info;
}
public void setStatus(int status){
this.status = status;
}
public int getStatus(){
return this.status;
}
public void setVersion(String version){
this.version = version;
}
public String getVersion(){
return this.version;
}
private JsonElement data;
public void setData(JsonElement data){
this.data = data;
}
public JsonElement getData(){
return this.data;
}
}
数据主体data我设置成JsonElement类型,他指json串的某一种元素,可以是JsonArray,JsonObject,或者java基本类型JsonPrimitive,好处是我可以判别数据类型做不同处理,其他javabean直接继承root就可以了,最后通过Gson去解析
小伙伴们可以下载我在github的demo然后更改RetrofitHelper里面BASE_URL,根据后台返回的json去适当更改订阅者onNext里面的解析方式,基本就可以用啦
github的demo地址https://github.com/huangkaisihuo/RetrofitRxandroidUtil
本人从事安卓开发工作,其实也是个小菜鸟,希望可以通过博客认识更多朋友,共同进步
路漫漫其修远兮,吾将上下而求索