学习笔记,自用,整理中
------------------------------------------------------------------------------------------------------------------
具体:
public interface EnjoyWeatherApi {
@POST("/v3/weather/weatherInfo")
CallpostWeather(@Field("city") String city, @Field("key") String key);
@GET("/v3/weather/weatherInfo")
CallgetWeather(@Query("city") String city, @Query("key") String key);
}
-----------------------------------------------------------------------------------------------------------------
@Target(METHOD)
@Retention(RUNTIME)
public @interface POST {
Stringvalue()default "";
}
---------------------------------------------------------------------------------------------------------------------
public class EnjoyRetrofit {
final MapserviceMethodCache =new ConcurrentHashMap<>();
final Call.FactorycallFactory;
final HttpUrlbaseUrl;
EnjoyRetrofit(Call.Factory callFactory, HttpUrl baseUrl) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
}
public T create(final Class service) {
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service},
new InvocationHandler() {
@Override
public Objectinvoke(Object proxy, Method method, Object[] args)throws Throwable {
//解析这个method 上所有的注解信息
ServiceMethod serviceMethod = loadServiceMethod(method);
//args:
return serviceMethod.invoke(args);
}
});
}
private ServiceMethodloadServiceMethod(Method method) {
//先不上锁,避免synchronized的性能损失
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 static final class Builder {
private HttpUrlbaseUrl;
//Okhttp->OkhttClient
private okhttp3.Call.FactorycallFactory; //null
public BuildercallFactory(okhttp3.Call.Factory factory) {
this.callFactory = factory;
return this;
}
public BuilderbaseUrl(String baseUrl) {
this.baseUrl = HttpUrl.get(baseUrl);
return this;
}
public EnjoyRetrofitbuild() {
if (baseUrl ==null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory =this.callFactory;
if (callFactory ==null) {
callFactory =new OkHttpClient();
}
return new EnjoyRetrofit(callFactory, baseUrl);
}
}
}
------------------------------------------------------------------------------------------------
public abstract class ParameterHandler {
abstract void apply(ServiceMethod serviceMethod, String value);
static class QueryParameterHandlerextends ParameterHandler {
Stringkey;
public QueryParameterHandler(String key) {
this.key = key;
}
//serviceMethod: 回调
@Override
void apply(ServiceMethod serviceMethod, String value) {
serviceMethod.addQueryParameter(key,value);
}
}
static class FiledParameterHandlerextends ParameterHandler {
Stringkey;
public FiledParameterHandler(String key) {
this.key = key;
}
@Override
void apply(ServiceMethod serviceMethod, String value) {
serviceMethod.addFiledParameter(key,value);
}
}
}
----------------------------------------------------------------------------------------
/**
* 记录请求类型 参数 完整地址
*/
public class ServiceMethod {
private final Call.FactorycallFactory;
private final StringrelativeUrl;
private final boolean hasBody;
private final ParameterHandler[]parameterHandler;
private FormBody.BuilderformBuild;
HttpUrlbaseUrl;
StringhttpMethod;
HttpUrl.BuilderurlBuilder;
public ServiceMethod(Builder builder) {
baseUrl = builder.enjoyRetrofit.baseUrl;
callFactory = builder.enjoyRetrofit.callFactory;
Thread xx =new AnyThread();
httpMethod = builder.httpMethod;
relativeUrl = builder.relativeUrl;
hasBody = builder.hasBody;
parameterHandler = builder.parameterHandler;
//如果是有请求体,创建一个okhttp的请求体对象
if (hasBody) {
formBuild =new FormBody.Builder();
}
}
public Objectinvoke(Object[] args) {
/**
* 1 处理请求的地址与参数
*/
for (int i =0; i
ParameterHandler handlers =parameterHandler[i];
//handler内本来就记录了key,现在给到对应的value
handlers.apply(this, args[i].toString());
}
//获取最终请求地址
HttpUrl url;
if (urlBuilder ==null) {
urlBuilder =baseUrl.newBuilder(relativeUrl);
}
url =urlBuilder.build();
//请求体
FormBody formBody =null;
if (formBuild !=null) {
formBody =formBuild.build();
}
Request request =new Request.Builder().url(url).method(httpMethod, formBody).build();
return callFactory.newCall(request);
}
// get请求, 把 k-v 拼到url里面
public void addQueryParameter(String key, String value) {
if (urlBuilder ==null) {
urlBuilder =baseUrl.newBuilder(relativeUrl);
}
urlBuilder.addQueryParameter(key, value);
}
//Post 把k-v 放到 请求体中
public void addFiledParameter(String key, String value) {
formBuild.add(key, value);
}
public static class Builder {
private final EnjoyRetrofitenjoyRetrofit;
private final Annotation[]methodAnnotations;
private final Annotation[][]parameterAnnotations;
ParameterHandler[]parameterHandler;
private StringhttpMethod;
private StringrelativeUrl;
private boolean hasBody;
public Builder(EnjoyRetrofit enjoyRetrofit, Method method) {
this.enjoyRetrofit = enjoyRetrofit;
//获取方法上的所有的注解
methodAnnotations = method.getAnnotations();
//获得方法参数的所有的注解 (一个参数可以有多个注解,一个方法又会有多个参数)
parameterAnnotations = method.getParameterAnnotations();
}
public ServiceMethodbuild() {
/**
* 1 解析方法上的注解, 只处理POST与GET
*/
for (Annotation methodAnnotation :methodAnnotations) {
if (methodAnnotationinstanceof POST) {
//记录当前请求方式
this.httpMethod ="POST";
//记录请求url的path
this.relativeUrl = ((POST) methodAnnotation).value();
// 是否有请求体
this.hasBody =true;
}else if (methodAnnotationinstanceof GET) {
this.httpMethod ="GET";
this.relativeUrl = ((GET) methodAnnotation).value();
this.hasBody =false;
}
}
/**
* 2 解析方法参数的注解
*/
int length =parameterAnnotations.length;
parameterHandler =new ParameterHandler[length];
for (int i =0; i < length; i++) {
// 一个参数上的所有的注解
Annotation[] annotations =parameterAnnotations[i];
// 处理参数上的每一个注解
for (Annotation annotation : annotations) {
//todo 可以加一个判断:如果httpMethod是get请求,现在又解析到Filed注解,可以提示使用者使用Query注解
if (annotationinstanceof Field) {
//得到注解上的value: 请求参数的key
String value = ((Field) annotation).value();
parameterHandler[i] =new ParameterHandler.FiledParameterHandler(value);
}else if (annotationinstanceof Query) {
String value = ((Query) annotation).value();
parameterHandler[i] =new ParameterHandler.QueryParameterHandler(value);
}
}
}
return new ServiceMethod(this);
}
}
}
--------------------------------------------------------------------------------------------------------
public class MainActivityextends AppCompatActivity {
private WeatherApiweatherApi;
private static final StringTAG ="MainActivity";
private EnjoyWeatherApienjoyWeatherApi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Retrofit retrofit =new Retrofit.Builder().baseUrl("https://restapi.amap.com")
.build();
weatherApi = retrofit.create(WeatherApi.class);
EnjoyRetrofit enjoyRetrofit =new EnjoyRetrofit.Builder().baseUrl("https://restapi.amap.com").build();
enjoyWeatherApi = enjoyRetrofit.create(EnjoyWeatherApi.class);
}
public void get(View view) {
Call call =weatherApi.getWeather("110101", "ae6c53e2186f33bbf240a12d80672d1b");
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
if (response.isSuccessful()){
ResponseBody body = response.body();
try {
String string = body.string();
Log.i(TAG, "onResponse get: " + string);
}catch (IOException e) {
e.printStackTrace();
}finally {
body.close();
}
}
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
}
public void post(View view) {
Call call =weatherApi.postWeather("110101", "ae6c53e2186f33bbf240a12d80672d1b");
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
ResponseBody body = response.body();
try {
String string = body.string();
Log.i(TAG, "onResponse post: " + string);
}catch (IOException e) {
e.printStackTrace();
}finally {
body.close();
}
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
}
public void enjoyGet(View view) {
okhttp3.Call call =enjoyWeatherApi.getWeather("110101", "ae6c53e2186f33bbf240a12d80672d1b");
call.enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response)throws IOException {
Log.i(TAG, "onResponse enjoy get: " + response.body().string());
response.close();
}
});
}
public void enjoyPost(View view) {
okhttp3.Call call =enjoyWeatherApi.postWeather("110101", "ae6c53e2186f33bbf240a12d80672d1b");
call.enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
}
@Override
public void onResponse(okhttp3.Call call, okhttp3.Response response)throws IOException {
Log.i(TAG, "onResponse enjoy post: " + response.body().string());
response.close();
}
});
}
}