val retrofit = Retrofit.Builder()
// 必填项
.baseUrl("http://www.baidu.com")
.client(OkHttpClient())
// 对得到的结果进行转换,常用的有加密解密,json转换等等
.addConverterFactory(StringConvertFactory())
// 对返回的结果进行封装,常用的有之间转化成Rxjava对象
// 这里我们简单的进行包装
.addCallAdapterFactory(ResponseWrapperCallAdapterFactory())
.build()
api = retrofit.create(TestApi::class.java)
Retrofit的通过构建者模式创建,这里的重点是:
api = retrofit.create(TestApi::class.java)
我们看看这个create方法是怎么解析接口文件的:
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();
@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.
// 如果参数的类型是Object,直接反射调用
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
// 如果是default方法,根据平台类型直接调用
// android平台固定返回false
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 通过Method,封装成okhttp请求
ServiceMethod
public ServiceMethod build() {
// 创建callAdapter
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
responseConverter = createResponseConverter();
// 解析注解
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
// 检查是否设置了请求方式
if (httpMethod == null) {
throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
}
// 如果没有添加body,要检查请求的方式是否支持无body请求
if (!hasBody) {
if (isMultipart) {
throw methodError(
"Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
}
if (isFormEncoded) {
throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
+ "request body (e.g., @POST).");
}
}
// 遍历参数的注解
int parameterCount = parameterAnnotationsArray.length;
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);
}
if (relativeUrl == null && !gotUrl) {
throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
}
if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
throw methodError("Non-body HTTP method cannot contain @Body.");
}
if (isFormEncoded && !gotField) {
throw methodError("Form-encoded method must contain at least one @Field.");
}
if (isMultipart && !gotPart) {
throw methodError("Multipart method must contain at least one @Part.");
}
return new ServiceMethod<>(this);
}
/**
* Created by li.zhipeng on 2018/8/29.
*
* 把得到网络请求结果String,转换成ResponseWrapper
*/
public class ResponseWrapperCallAdapterFactory extends CallAdapter.Factory {
@Override
public CallAdapter get(@NonNull final Type returnType, @NonNull Annotation[] annotations, @NonNull Retrofit retrofit) {
return new CallAdapter() {
@Override
public Type responseType() {
return returnType;
}
@Override
public ResponseWrapper adapt(@NonNull Call call) {
try {
return new ResponseWrapper(call.execute().body());
} catch (IOException e) {
e.printStackTrace();
}
return new ResponseWrapper("error");
}
};
}
}
这个类的重点就是:
@Override
public ResponseWrapper adapt(@NonNull Call call) {
try {
return new ResponseWrapper(call.execute().body());
} catch (IOException e) {
e.printStackTrace();
}
return new ResponseWrapper("error");
}
我们在CallAdapter中开启了网络请求,并且把得到的结果封装成我们需要的对象。在动态代理中
serviceMethod.adapt(okHttpCall);
T adapt(Call call) {
return callAdapter.adapt(call);
}
Android中的Toast是一种简易的消息提示框,toast提示框不能被用户点击,toast会根据用户设置的显示时间后自动消失。
创建Toast
两个方法创建Toast
makeText(Context context, int resId, int duration)
参数:context是toast显示在
angular.identiy 描述: 返回它第一参数的函数. 此函数多用于函数是编程. 使用方法: angular.identity(value); 参数详解: Param Type Details value
*
to be returned. 返回值: 传入的value 实例代码:
<!DOCTYPE HTML>
Hierarchical Queries
If a table contains hierarchical data, then you can select rows in a hierarchical order using the hierarchical query clause:
hierarchical_query_clause::=
start with condi
初次接触到socket网络编程,也参考了网络上众前辈的文章。尝试自己也写了一下,记录下过程吧:
服务端:(接收客户端消息并把它们打印出来)
public class SocketServer {
private List<Socket> socketList = new ArrayList<Socket>();
public s