基本使用
GitHub网址:https://github.com/square/retrofit
添加依赖:
compile ‘com.squareup.retrofit2:retrofit:2.3.0’
compile ‘com.squareup.retrofit2:converter-gson:+’
compile ‘com.squareup.okhttp3:logging-interceptor:+’
ServiceApi接口
public interface ServiceApi {
@GET("is_login")//Query代表你要查询的字段名字
Call<UserLoginResult> userlogin(@Query("username") String userName,@Query("password")String password);
}
RetrofitClient进行封装
public class RetrofitClient {
private static final ServiceApi mServiceApi;
static {
OkHttpClient okHttpClient=new OkHttpClient();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://app.ahhuabang.com:8088/server/index.php/user/")
// 添加解析转换工厂,Gson 解析,Xml解析,等等
.addConverterFactory(GsonConverterFactory.create())
//不设置默认的是okHttp
.client(okHttpClient)
.build();
mServiceApi = retrofit.create(ServiceApi.class);
}
public static ServiceApi getServiceApi() {
return mServiceApi;
}
}
UserLoginResult:返回的结果
public class UserLoginResult {
private String msg;
private String token;
@Override
public String toString() {
return "UserInfo{" +
"msg='" + msg + '\'' +
", token='" + token + '\'' +
'}';
}
}
测试
final Call<UserLoginResult> userlogin = RetrofitClient.getServiceApi().userlogin("测试专用", "HB654321");
userlogin.enqueue(new Callback<UserLoginResult>() {
@Override
public void onResponse(Call<UserLoginResult> call, Response<UserLoginResult> response) {
Log.e("TAG", response + "");
UserLoginResult userLoginResult = response.body();
Log.e("TAG", userLoginResult.toString());
}
@Override
public void onFailure(Call<UserLoginResult> call, Throwable t) {
t.printStackTrace();
}
});
常见问题1:没有打印,想知道Url等参数,这时候可以通过okhttp添加拦截器
OkHttpClient okHttpClient=new OkHttpClient.Builder().
addInterceptor(new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
//默认是Log.d修改成Log.e
Log.e("Retorfit",message);
}
}).setLevel(HttpLoggingInterceptor.Level.BODY)).build();
2. 数据格式不一致,我们这里成功 没有data,但是有时候我们返回的是有data,而data成功的时候可能是个对象,但是失败的时候返回的是String类型
userInfo
public class UserInfo {
private String msg;
private String token;
@Override
public String toString() {
return "UserInfo{" +
"msg='" + msg + '\'' +
", token='" + token + '\'' +
'}';
}
}
BaseResult
public class BaseResult {
private String msg;
private String code;
public String getMsg() {
return msg;
}
public String getCode() {
return code;
}
public boolean isOk() {
return "0".equals(code);
}
}
Result
public class Result<T> extends BaseResult{
public Object data;
}
修改ServiceApi
public interface ServiceApi {
@GET("is_login")//Query代表你要查询的字段名字
Call<Result<UserInfo>> userlogin(@Query("username") String userName, @Query("password") String password);
}
HttpCallback封装
public abstract class HttpCallback<T> implements Callback<Result<T>> {
@Override
public void onResponse(Call<Result<T>> call, Response<Result<T>> response) {
Result<T> result = response.body();
if (!result.isOk()) {
onError(result.getCode(), result.getMsg());
return;
}
//解析上面泛型的类
Class<T> dataClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
Gson gson = new Gson();
if (result.data != null) {
T data = gson.fromJson(result.data.toString(), dataClass);
onSucceed(data);
}
}
@Override
public void onFailure(Call<Result<T>> call, Throwable t) {
}
public abstract void onSucceed(T result);
public abstract void onError(String code, String msg);
}
测试
Call<Result<UserInfo>> userlogin = RetrofitClient.getServiceApi().userlogin("测试专用", "HB654321");
userlogin.enqueue(new HttpCallback<UserInfo>() {
@Override
public void onSucceed(UserInfo result) {
Log.e("TAG", result.toString());
}
@Override
public void onError(String code, String msg) {
}
});
源码设计模式分析
Builder 设计模式
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://app.ahhuabang.com:8088/server/index.php/user/")
.addConverterFactory(GsonConverterFactory.create())
.client(okHttpClient)
.build();
retrofit.create(ServiceApi.class)动态代理设计模式
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
//适配器模式
return serviceMethod.adapt(okHttpCall);
}
});
}
用作解耦,体现的形式有很多,插件化绕过 AndroidManifest.xml 主要是用作 Hook 拦截方法,MVP 主要用作 AOP 切面,总之采用的原理其实还是方法的拦截
工厂方法模式:简单工厂模式,抽象工厂模式,方法工厂模式
方法工厂模式
public static GsonConverterFactory create(Gson gson) {
if (gson == null) throw new NullPointerException("gson == null");
return new GsonConverterFactory(gson);
}
抽象方法工厂模式
GsonConverterFactory extends Converter.Factory
简单工厂设计模式
private static Platform findPlatform() {
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
try {
Class.forName("java.util.Optional");
return new Java8();
} catch (ClassNotFoundException ignored) {
}
return new Platform();
}
adapter设计模式
serviceMethod.adapt(okHttpCall)
如果不采用rxjava直接返回okhttpCall对象,而采用rxjava返回的应该是Observable对象,这里作用就是将Call对象转换成Observable对象
模板设计模式ParameterHandler
abstract void apply(RequestBuilder builder, @Nullable T value) throws IOException;
static final class RelativeUrl extends ParameterHandler<Object> {
@Override void apply(RequestBuilder builder, @Nullable Object value) {
checkNotNull(value, "@Url parameter is null.");
builder.setRelativeUrl(value);
}
}
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
if (Utils.hasUnresolvableType(parameterType)) {
throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
parameterType);
}
Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
if (parameterAnnotations == null) {
throw parameterError(p, "No Retrofit annotation found.");
}
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
private ParameterHandler<?> parseParameterAnnotation(){
if (type == HttpUrl.class
|| type == String.class
|| type == URI.class
|| (type instanceof Class && "android.net.Uri".equals(((Class<?>) type).getName()))) {
return new ParameterHandler.RelativeUrl();
}
return new ParameterHandler.Path<>(name, converter, path.encoded());
return new ParameterHandler.Query<>(name, converter, encoded).array();
}
制定通用的流程,具体的算法细节由不同的子类去实现,确定Retrofit请求流程 ,解析方法参数注解,但是其具体的各个参数细节由子类去实现
还可以衍生另一种设计模式叫做策略,不同的参数注解采用不同的添加策略
享元设计模式:对对象进行复用
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
原型设计模式
public interface Call<T> extends Cloneable {
}
单例,观察者(也可以说是回调)