public T create(final Class> service) {
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[]{service}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall(serviceMethod, args);
return serviceMethod.adapt(okHttpCall);
}
});
}
ServiceMethod
public class ServiceMethod {
//请求类型 POST GET
private String httpMethod;
//请求的地址 不包含baseUrl;
private String mRelativeUrl;
private ParameterHandler[] mParameterHandler;
private final Retrofit mRetrofit;
private HttpUrl.Builder mUrlBuilder;
private final okhttp3.Call.Factory mCallFactroy;
private FormBody.Builder mFormBody;
private RequestBody mRequestBody;
private Method mMethod;
private CallAdapter callAdapter;
public ServiceMethod(Builder builder) {
mMethod = builder.mMethod;
mRetrofit = builder.mRetrofit;
httpMethod = builder.httpMethod;
mRelativeUrl = builder.mRelativeUrl;
mParameterHandler = builder.mParameterHandler;
mCallFactroy = mRetrofit.callFactroy();
callAdapter = (CallAdapter) mRetrofit.callAdapter().get();
}
public Method getMethod() {
return mMethod;
}
public Call toCall(Object[] args) {
//创建Okhttp Request
Request.Builder requestBuilder = new Request.Builder();
//确定地址请求地址
if (mUrlBuilder == null) {
mUrlBuilder = mRetrofit.getBaseUrl().newBuilder(mRelativeUrl);
}
for (int i = 0; i < mParameterHandler.length; i++) {
mParameterHandler[i].appley(this, String.valueOf(args[i]));
}
requestBuilder.url(mUrlBuilder.build());
requestBuilder.method(httpMethod, null);
Request request = requestBuilder.build();
return mCallFactroy.newCall(request);
}
//get请求Query 注解
public void addQueryParameter(String name, String value) {
mUrlBuilder.addQueryParameter(name, value);
}
public T adapt(Call call) {
Type genericReturnType = mMethod.getGenericReturnType();
Class> rawType = getRawType(genericReturnType);
//判断方法返回类型 是Call 直接用默认的callAdapter
if (rawType == Call.class) {
return (T) DefaultCallAdapterFactory.INSTANCE.get().adapt(call);
}
//使用传入的RxJava2CallAdapterFactory
return callAdapter.adapt(call);
}
Class> getRawType(Type type) {
checkNotNull(type, "type == null");
if (type instanceof Class>) {
// Type is a normal class.
return (Class>) type;
}
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
// I'm not exactly sure why getRawType() returns Type instead of Class. Neal isn't either but
// suspects some pathological case related to nested classes exists.
Type rawType = parameterizedType.getRawType();
if (!(rawType instanceof Class)) throw new IllegalArgumentException();
return (Class>) rawType;
}
if (type instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) type).getGenericComponentType();
return Array.newInstance(getRawType(componentType), 0).getClass();
}
if (type instanceof TypeVariable) {
// We could use the variable's bounds, but that won't work if there are multiple. Having a raw
// type that's more general than necessary is okay.
return Object.class;
}
if (type instanceof WildcardType) {
return getRawType(((WildcardType) type).getUpperBounds()[0]);
}
throw new IllegalArgumentException("Expected a Class, ParameterizedType, or "
+ "GenericArrayType, but <" + type + "> is of type " + type.getClass().getName());
}
public static final class Builder {
private final Annotation[] mMethodAnnotations;
private final Annotation[][] mParameterAnnotations;
private final Retrofit mRetrofit;
//请求类型 POST GET
private String httpMethod;
//请求的地址 不包含baseUrl;
private String mRelativeUrl;
private ParameterHandler[] mParameterHandler;
private Method mMethod;
public Builder(Retrofit retrofit, Method method) {
mMethod = method;
mRetrofit = retrofit;
//拿到该方法注解
mMethodAnnotations = method.getAnnotations();
//拿到方法注解
mParameterAnnotations = method.getParameterAnnotations();
}
public ServiceMethod build() {
//处理方法注解
for (Annotation methodAnnotation : mMethodAnnotations) {
paresMethodAnnotation(methodAnnotation);
}
paresParameterAnnotation();
return new ServiceMethod(this);
}
private void paresMethodAnnotation(Annotation methodAnnotation) {
if (methodAnnotation instanceof GET) {
httpMethod = "GET";
GET get = (GET) methodAnnotation;
mRelativeUrl = get.value();
}
}
private void paresParameterAnnotation() {
//处理参数
mParameterHandler = new ParameterHandler[mParameterAnnotations.length];
for (int i = 0; i < mParameterAnnotations.length; i++) {
Annotation[] parameterAnnotation = mParameterAnnotations[i];
//遍历一个参数上的所有注解
for (Annotation annotation : parameterAnnotation) {
if (annotation instanceof Query) {
Query query = (Query) annotation;
String value = query.value();
mParameterHandler[i] = new ParameterHandler.Query(value);
}
}
}
}
}
}
ParameterHandler
public abstract class ParameterHandler {
abstract void appley(ServiceMethod method, String value);
static class Query extends ParameterHandler {
private final String mName;
public Query(String name) {
this.mName = name;
}
@Override
void appley(ServiceMethod method, String value) {
method.addQueryParameter(mName, value);
}
}
}
OkHttpCall
public class OkHttpCall implements Call {
final ServiceMethod serviceMethod;
final Object[] args;//自己传入的值
public OkHttpCall(ServiceMethod serviceMethod, Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
@Override
public void enqueue(final Callback callback) {
okhttp3.Call call = serviceMethod.toCall(args);
call.enqueue(new okhttp3.Callback() {
@Override
public void onFailure(okhttp3.Call call, IOException e) {
if (callback != null) {
callback.onFailure(OkHttpCall.this, e);
}
}
@Override
public void onResponse(okhttp3.Call call, Response response) throws IOException {
IResponse rResponse = new IResponse();
rResponse.body = parseBody(response.body());
if (callback != null) {
callback.onResponse(OkHttpCall.this, rResponse);
}
}
});
}
@Override
public IResponse execute() {
okhttp3.Call call = serviceMethod.toCall(args);
try {
IResponse objectResponse = new IResponse<>();
objectResponse.body=parseBody(call.execute().body());
return (IResponse) objectResponse;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public T parseBody(ResponseBody response) {
Type returnType = serviceMethod.getMethod().getGenericReturnType();
Class dataClass = (Class) ((ParameterizedType) returnType).getActualTypeArguments()[0];
Gson gson = new Gson();
T body = gson.fromJson(response.charStream(), dataClass);
return body;
}
}
Call
public interface Call {
void enqueue(Callback callback);
IResponse execute();
}
CallAdapter
public interface CallAdapter {
T adapt(Call call);
abstract class Factory {
public abstract CallAdapter, ?> get();
}
}
Callback
public interface Callback {
void onResponse(Call call, IResponse response);
void onFailure(Call call, Throwable t);
}
public final class IResponse {
public T body;
}
DefaultCallAdapterFactory 默认的callAdapter
public class DefaultCallAdapterFactory extends CallAdapter.Factory {
public static DefaultCallAdapterFactory INSTANCE = new DefaultCallAdapterFactory();
@Override
public CallAdapter get() {
return new CallAdapter
RxJava2CallAdapterFactory 支持rxjava的callAdapter
public class RxJava2CallAdapterFactory extends CallAdapter.Factory {
@Override
public CallAdapter, ?> get() {
return new RxJava2CallAdapter();
}
}
public class RxJava2CallAdapter implements CallAdapter {
@Override
public Object adapt(Call call) {
Observable responseObservable = new CallObservable<>(call);
return responseObservable;
}
}
final class CallObservable extends Observable {
private final Call originalCall;
CallObservable(Call originalCall) {
this.originalCall = originalCall;
}
@Override
protected void subscribeActual(Observer super T> observer) {
IResponse response = originalCall.execute();
T body = response.body;
observer.onNext(body);
observer.onComplete();
}
}
原题链接:#137 Single Number II
要求:
给定一个整型数组,其中除了一个元素之外,每个元素都出现三次。找出这个元素
注意:算法的时间复杂度应为O(n),最好不使用额外的内存空间
难度:中等
分析:
与#136类似,都是考察位运算。不过出现两次的可以使用异或运算的特性 n XOR n = 0, n XOR 0 = n,即某一
A message containing letters from A-Z is being encoded to numbers using the following mapping:
'A' -> 1
'B' -> 2
...
'Z' -> 26
Given an encoded message containing digits, det