retrofit基本使用和源码设计模式分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_24675479/article/details/79831828

基本使用

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 {
}

单例,观察者(也可以说是回调)

猜你喜欢

转载自blog.csdn.net/qq_24675479/article/details/79831828