使用用Retrofit +Rxjava网络框架
2017-05-02 本文已影响46人
大数据修行
1.最先配置网络处理器ApiGenerator
/**
* 接口生成器
*/
public class ApiGenerator {
private static String HOST;
private static Retrofit retrofit;
static {
if (BuildConfig.PRODUCT_MODE) {
//生产环境
HOST = BuildConfig.API_BASE_URL;
} else {
HOST = BuildConfig.API_TEST_BASE_URL;
}
// Create a trust manager that does not validate certificate chains
//创建能够访问https的方法
X509TrustManager trustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(final X509Certificate[] chain, final String authType) {
}
@Override
public void checkServerTrusted(final X509Certificate[] chain, final String authType) {
}
@Override public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
SSLContext sslContext = null;
try {
// Install the all-trusting trust manager
sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { trustManager }, new SecureRandom());
} catch (Exception ignore) {
}
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
@Override public boolean verify(final String hostname, final SSLSession session) {
return true;
}
};
// 公共参数配置
Interceptor commonParamsInterceptor = new CommonParamsInterceptor();
//log拦截
Interceptor loggingInterceptor = new HttpLoggingInterceptor().setLevel(
BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY
: HttpLoggingInterceptor.Level.NONE);
Dispatcher dispatcher = new Dispatcher(Executors.newScheduledThreadPool(3));
OkHttpClient.Builder builder =
new OkHttpClient.Builder().connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.MINUTES)
.writeTimeout(1, TimeUnit.MINUTES)
.dispatcher(dispatcher)//线程
.addInterceptor(commonParamsInterceptor)
.addInterceptor(
loggingInterceptor); // 日志拦截器若设置为network拦截器,则打印不了返回数据,所以这里设置成"上层"拦截器
if (sslContext != null) {
builder.sslSocketFactory(sslContext.getSocketFactory(), trustManager)
.hostnameVerifier(hostnameVerifier);
}
OkHttpClient okHttpClient = builder.build();
retrofit = new Retrofit.Builder().addCallAdapterFactory(RxJava2CallAdapterFactory.create())
//Rxjava转换
.baseUrl(HOST)
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create())//Gson转换
.build();
}
/**
* 创建接口
*/
public static <S> S createApi(Class<S> apiClass) {
return retrofit.create(apiClass);
}
}
2.写一个基类,便于复用解析处理
public class BaseResp<T> {
@SerializedName("code")
public int code;
@SerializedName("msg")
public String msg;
@SerializedName("data")
public T data;
}
3.然后把相关网络接口都写到一个接口中去,如登录注册相关接口
public interface UserLoginApi {
/**
* 发送手机验证码
*
* @param mobile 手机号
* @param type 短信内容类型,int整型,不填或0:表示注册短信验证码。1:修改密码
*
* @return
*/
@FormUrlEncoded
@POST(ApiPath.SEND_VERIFY_CODE)
Single<BaseResp<Void>> sendVerifyCode(
@Field("mobile") String mobile,
@Field("type") int type
);
/**
* 登录
*
* @param userName 用户名:手机号或者UM账号
* @param pwd 密码:数字、字母、符号的组合,至少8位以上,区分大小写 需AES(AES/ECB/PKCS5Padding,UTF-8,Base64)加密
*
* @return
*/
@FormUrlEncoded
@POST(ApiPath.LOGIN)
Single<BaseResp<LoginData>> login(
@Field("userName") String userName,
@Field("pwd") String pwd
);
/**
* 免登录
*
* @param userId 用户id
* @param token 身份令牌
*
* @return
*/
@FormUrlEncoded
@POST(ApiPath.NO_LOGIN)
Single<BaseResp<LoginData>> noLogin(
@Field("userId") int userId,
@Field("token") String token
);
/**
* 校验手机验证码
*
* @param mobile 手机号
* @param verifyCode 验证码
*
* @return
*/
@FormUrlEncoded
@POST(ApiPath.CHECK_VERIFY_CODE)
Single<BaseResp<Void>> checkVerifyCode(
@Field("mobile") String mobile,
@Field("verifyCode") String verifyCode
);
/**
* 用户注册
*
* @param mobile 手机号
* @param pwd 密码
*
* @return
*/
@FormUrlEncoded
@POST(ApiPath.REGISTER)
Single<BaseResp<LoginData>> register(
@Field("mobile") String mobile,
@Field("pwd") String pwd
);
/**
* 绑定UM账号
*
* @param userId 用户id
* @param token 身份令牌
* @param mobile 手机号
* @param umAccount um账号
* @param umPwd um密码
*
* @return
*/
@FormUrlEncoded
@POST(ApiPath.BIND_TO_UM)
Single<BaseResp<UserInfoData>> bindToUm(
@Field("userId") int userId,
@Field("token") String token,
@Field("mobile") String mobile,
@Field("umAccount") String umAccount,
@Field("umPwd") String umPwd
);
/**
* 修改密码
*
* @param mobile 手机号
* @param newPwd 新密码
* @param type 0:忘记密码,1:修改密码,当1时不需传token和旧密码
*
* @return
*/
@FormUrlEncoded
@POST(ApiPath.CHANGE_PWD)
Single<BaseResp<Void>> changePwd(
@Field("userId") int userId,
@Field("token") String token,
@Field("mobile") String mobile,
@Field("newPwd") String newPwd,
@Field("type") int type
);
}
调用的时候
有一个转换类
/**
* Resp数据转换器,统一了错误码处理,返回最终关心的实际结果数据
*
* Created by yelongfei490 on 16/11/22.
*/
public class RespTransformer<T> implements SingleTransformer<BaseResp<T>, T> {
@Override public SingleSource<T> apply(Single<BaseResp<T>> upstream) {
return upstream.subscribeOn(Schedulers.io()).map(new Function<BaseResp<T>, T>() {
@Override public T apply(BaseResp<T> baseResp) throws Exception {
int code = baseResp.code;
if (code == ErrorCode.SUCCESS) {
return baseResp.data;
} else if ( // token错误重登处理
code == ErrorCode.TOKEN_EMPTY ||
code == ErrorCode.TOKEN_ILLEGAL ||
code == ErrorCode.TOKEN_INVALID ||
code == ErrorCode.TOKEN_NOT_MATCHING_USER) {
new UserBiz().quitLogin();
throw new ApiError(code, ResourceUtils.getString(R.string.user_token_invalid));
} else {
throw new ApiError(code, baseResp.msg);
}
}
}).observeOn(AndroidSchedulers.mainThread());
}
}
ApiGenerator.createApi(UserLoginApi.class)
.register(mobile, pwd)
.compose(new RespTransformer<LoginData>())
.subscribe(new BaseSingleObserver<LoginData>() {
@Override public void onSuccess(LoginData value) {
...balabala...
dismissLoadingDialog();
}
@Override public void onError(Throwable e) {
...balabala...
}
});
这样就可以了