二.Retrofit是什么,有哪些API,有什么好处(what)
1.先看Retrofit的文档 https://square.github.io/retrofit/
A type-safe HTTP client for Android and Java 这里看这个 type-safe,Retrofit通过泛型来约束我们想要的对象,自己不用去解析数据
例子:
public interface GitHubService {
@GET("api/data/福利/{pageCount}/{pageIndex}")
Call>> defautBenefits(
@Path("pageCount") int pageCount,
@Path("pageIndex") int pageIndex
);
}
public class BaseModel {
public boolean error;
public T results;
}
public class Benefit {
/**
* _id : 5a8e0c41421aa9133298a259
* createdAt : 2018-02-22T08:18:09.547Z
* desc : 2-22
* publishedAt : 2018-02-22T08:24:35.209Z
* source : chrome
* type : 福利
* url : https://ws1.sinaimg.cn/large/610dc034ly1foowtrkpvkj20sg0izdkx.jpg
* used : true
* who : 代码家
*/
private String _id;
private String createdAt;
private String desc;
private String publishedAt;
private String source;
private String type;
private String url;
private boolean used;
private String who;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public boolean isUsed() {
return used;
}
public void setUsed(boolean used) {
this.used = used;
}
public String getWho() {
return who;
}
public void setWho(String who) {
this.who = who;
}
}
三.debug拎出主线逻辑(how) debug!debug!debug!
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://gank.io/")
.addConverterFactory(GsonConverterFactory.create())
.build();
retrofit 通过Builder模式来创建,先看看build()方法
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
1.okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
2.Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
3.List adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// Make a defensive copy of the converters.
4. List converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
public T create(final Class service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
//动态代理模式
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
//当调用api方法时,就会触发invoke
@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);
}
//通过对注解的处理转换成我们想要的参数
//dapts an invocation of an interface method into an HTTP call.
//例如:pageCount=20 pageIndex=1
ServiceMethod
最后返回的call调用enqueue方法
@Override public void enqueue(final Callback callback) {
checkNotNull(callback, "callback == null");
//代理delegate其实就是call
delegate.enqueue(new Callback() {
@Override public void onResponse(Call call, final Response response) {
//最后切回到主线程中执行了
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
//请求成功后进行回调
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
总结一下: Retrofit build Retrofit create proxy for API interface API method intercepted by proxy parse params with ServiceMethod build HttpCall with params CallAdapter adapts Call to T enqueue() waiting for callback 四.直接看源码,画流程图
public ServiceMethod build() {
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
if (responseType == Response.class || responseType == okhttp3.Response.class) {
throw methodError("'"
+ Utils.getRawType(responseType).getName()
+ "' is not a valid response body type. Did you mean ResponseBody?");
}
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
//进行解析注解
parseMethodAnnotation(annotation);
}
.......
省略代码了
.......
private CallAdapter createCallAdapter() {
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(
"Method return type must not include a type variable or wildcard: %s", returnType);
}
if (returnType == void.class) {
throw methodError("Service methods cannot return void.");
}
Annotation[] annotations = method.getAnnotations();
try {
//跳进这个方法
return (CallAdapter) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(e, "Unable to create call adapter for %s", returnType);
}
}
public CallAdapter, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
Annotation[] annotations) {
checkNotNull(returnType, "returnType == null");
checkNotNull(annotations, "annotations == null");
int start = adapterFactories.indexOf(skipPast) + 1;
//对于CallAdapter我们在Retrofit build的时候把它初始化
//在这里取出相应的adapter,如果我们不添加,默认的是ExecutorCallAdapterFactory
//如果想配合RxJava使用(又是一种类型)
//addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//还要Java8、、、
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
.append(returnType)
.append(".\n");
if (skipPast != null) {
builder.append(" Skipped:");
for (int i = 0; i < start; i++) {
builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
}
builder.append('\n');
}
builder.append(" Tried:");
for (int i = start, count = adapterFactories.size(); i < count; i++) {
builder.append("\n * ").append(adapterFactories.get(i).getClass().getName());
}
throw new IllegalArgumentException(builder.toString());
}
然后再调用adapt()方法,看一下ExecutorCallAdapterFactory中的方法
@Override
// Android中默认返回的是Call,在RxJava中返回Observable
public CallAdapter, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call adapt(Call call) {
//这里传递进来的是OkHttpCall
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
@Override void apply(RequestBuilder builder, @Nullable T value) {
if (value == null) {
throw new IllegalArgumentException("Body parameter value must not be null.");
}
RequestBody body;
try {
// !!!!!!!!在这里 GsonResponseBodyConverter实现了这个方法
body = converter.convert(value);
} catch (IOException e) {
throw new RuntimeException("Unable to convert " + value + " to RequestBody", e);
}
builder.setBody(body);
}
1. If语句作为表达式
val properties = if (jobIdToActiveJob.contains(jobId)) {
jobIdToActiveJob(stage.jobId).properties
} else {
// this stage will be assigned to "default" po
基础测试题
卷面上不能出现任何的涂写文字,所有的答案要求写在答题纸上,考卷不得带走。
选择题
1、 What will happen when you attempt to compile and run the following code? (3)
public class Static {
static {
int x = 5; // 在static内有效
}
st
表里的一行对于一个数据块太大的情况有二种(一行在一个数据块里放不下)
第一种情况:
INSERT的时候,INSERT时候行的大小就超一个块的大小。Oracle把这行的数据存储在一连串的数据块里(Oracle Stores the data for the row in a chain of data blocks),这种情况称为行链接(Row Chain),一般不可避免(除非使用更大的数据
Follow up for "Remove Duplicates":What if duplicates are allowed at most twice?
For example,Given sorted array nums = [1,1,1,2,2,3],
Your function should return length