RPCService网络框架
SourceService sourceService = NetUriWrapper.newRpcService(
mContext, SourceService.class, Constant.BASE_TEST_URL, null);
sourceService.getContents(request, new DDRpcCallback() {…}
此处的自定义service需要继承rpcservice接口
public static T newRpcService(Context context, Class clazz, String url, Object request) {
if (request != null) {
String json = (new GsonBuilder()).serializeNulls().create().toJson(request);
return (new RpcServiceFactory(context)).newRpcService(clazz, url + (url.endsWith(“/”) ? “” : “/”) + “SignParam=” + URLEncoder.encode(json));
} else {
return (new RpcServiceFactory(context)).newRpcService(clazz, url);
}
}
外部调用,通过RPCServiceFactory
初始化 RpcClientFactoryService;
通过RpcClientFactoryService 初始化RpcClient;
通过动态代理生成网络请求的代理类(比如此处的sourceservice);
public RpcServiceFactory(final Context context) {
this.mContext = context.getApplicationContext();
this.mClientFactoryService = new RpcClientFactoryService(this.mContext);
}
创建RpcClientFactoryService
//加载所有添加注解@ServiceProvider(RpcClientFactory.class)的实例
static final ServiceLoader FACTORIES = ServiceLoader.load(RpcClientFactory.class);
public RpcClient<? extends RpcRequest, ? extends RpcResponse> getRpcClient(final Uri uri) {
final String scheme = uri.getScheme();
for (final RpcClientFactory factory : FACTORIES) {
if (factory.isSchemeSupported(scheme)) {
//协议匹配上通过自定义RpcClientFactory获取RpcClient
record(getClass(), false, SDCARD_RPC_CRASH_DUMP_LOG);
return factory.newRpcClient(this.mContext);
}
}
record(getClass(), true, SDCARD_RPC_CRASH_DUMP_LOG);
try {
if (null != sDefaultClientFactoryObj) {
if (null != sIsSchemeSupportedMethod) {
boolean supported = (boolean) sIsSchemeSupportedMethod.invoke(sDefaultClientFactoryObj, scheme);
if (supported && sNewRpcClientMethod != null) {
//没有自定义RpcClientFactory或未匹配上协议,则通过默认的RpcClientFactory
//(在static块中通过反射初始化的HttpRpcClientFactory)来获取RpcClient对象:默认支持http与https协议
return (RpcClient<? extends RpcRequest, ? extends RpcResponse>) sNewRpcClientMethod.invoke(sDefaultClientFactoryObj, this.mContext);
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
throw new UnsupportedSchemeException(scheme);
}
创建client
T newRpcService(final Class clazz, final Uri uri, final Object ref) {
return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz }, new RpcServiceProxy(this, clazz, uri, ref));
}
RpcServiceProxy(final RpcServiceFactory factory, final Class<? extends RpcService> clazz, final Uri uri, final Object ref) { this.mSvcFactory = factory; this.mRpcClazz = clazz; this.mRpcUri = uri; this.mRpcMethods = Collections.unmodifiableSet(new HashSet(Arrays.asList(this.mRpcClazz.getMethods()))); //获取所有rpc类的方法 this.mRef = ref; this.mTransporter = this.getServiceTransporter(clazz); this.mHandler = new Handler(Looper.getMainLooper()); } public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable { if (this.mRpcMethods.contains(method)) { //包含当前方法 final Class<?>[] exceptionTypes = method.getExceptionTypes();
try {
return execute(proxy, method, args);//真正执行
} catch (final RuntimeException e) {
throw e;
} catch (final Throwable e) {
for (final Class<?> exceptionType : exceptionTypes) {
if (exceptionType.isAssignableFrom(e.getClass())) {
throw e;
}
}
throw new RuntimeException(e);
}
}
if (OBJECT_METHODS.contains(method)) {
return method.invoke(proxy, args); //此处为默认object方法
}
throw new NoSuchMethodException(method.toGenericString());
}
创建代理类,如果执行了自定义rpc接口中的方法,会走到代理类execute中
private Object execute(Object proxy, Method method, Object[] args) throws Throwable {
final Class<?> returnType = method.getReturnType();
final RpcClient.Builder clientBuilder = this.mSvcFactory.getRpcClient(this.mRpcUri.getScheme()).newBuilder();
//获取client
setRpcInterceptors(method, clientBuilder);
//遍历注解,设置拦截器
setRpcOptions(method, clientBuilder);
//遍历注解,增加失败重试策略
setDnsResolver(method, clientBuilder);
//遍历注解,设置域名解析策略
setRpcTransporter(method, clientBuilder);
//遍历注解,数据传输配置
// Execute RPC
final RpcClient client = clientBuilder.build();
final RpcRequest request = client.newRequestBuilder()
.setUrl(this.mRpcUri.toString())
.setRpcClient(client)
.setRpcService(this.mRpcClazz, method, args)
//这里设置request的信息,获取注解,添加path,request对象,http method
.build();
final Rpc<RpcRequest, RpcResponse> rpc = client.newRpc(request);
final boolean async = null != args && args.length > 0 && args[args.length - 1] instanceof RpcService.Callback;
final Object result;
if (async) {//如果是异步操作
final RpcService.Callback<Object> callback = (RpcService.Callback<Object>) args[args.length - 1];
final ThreadType threadType = getTargetThreadType(method, args);
result = rpc.enqueue(new Rpc.Callback<RpcRequest, RpcResponse>() {
//最终调用okhttprpc的enqueue0,再调用realcall.newcall.enqueue
//再调用dispatcher.enqueue,执行AsyncCall,这个call放在下面解释
@Override
public void onSuccess(final RpcResponse response) {
try {
final Object result = response.getContent();
switch (threadType) {//线程模式
case MAIN:
mHandler.post(new Runnable() {//切换到主线程
public void run() {
try {
callback.onSuccess(result);
} catch (final Throwable t) {
callOnFailure(request, callback, new IOException(t));
}
}
});
break;
default:
try {
callback.onSuccess(result);
} catch (final Throwable t) {
callOnFailure(request, callback, new IOException(t));
}
break;
}
} catch (final IOException e) {
onFailure(request, e);
} catch (final Throwable t) {
onFailure(request, new IOException(t));
}
}
@Override
public void onFailure(final RpcRequest request, final IOException e) {
...
}
});
if (Rpc.class.isAssignableFrom(returnType)) {
return rpc;
}
} else {
result = rpc.execute().getContent(); //同步
}
if (void.class.equals(returnType) || Void.class.equals(returnType)) {
return null;
}
return result;
}
AsyncCall
final class AsyncCall extends NamedRunnable {
private final Callback responseCallback;
AsyncCall(Callback responseCallback) {
super(“OkHttp %s”, new Object[]{RealCall.this.redactedUrl()});
this.responseCallback = responseCallback;
}
String host() {
return RealCall.this.originalRequest.url().host();
}
Request request() {
return RealCall.this.originalRequest;
}
RealCall get() {
return RealCall.this;
}
protected void execute() {
RealCall.this.statisticalContext.traceExecuteTime();
int tid = Process.myTid();
RealCall.this.logEventListener.callStart(RealCall.this, tid);
boolean signalledCallback = false;
String oldName = Thread.currentThread().getName();
Thread.currentThread().setName(String.format(“OneNet %s”, RealCall.fixUrl(RealCall.this.originalRequest.url.toString())));
try {
Response response = RealCall.this.getResponseWithInterceptorChain();
//真正执行,添加拦截链,包括client的,还有其他拦截器。
if (RealCall.this.retryAndFollowUpInterceptor.isCanceled()) {
signalledCallback = true;
this.responseCallback.onFailure(RealCall.this, new IOException(“Canceled”));
} else {
signalledCallback = true;
this.responseCallback.onResponse(RealCall.this, response);
}
} catch (IOException var8) {
RealCall.this.logEventListener.callFailed(RealCall.this, var8);
if (signalledCallback) {
Platform.get().log(4, "Callback failure for " + RealCall.this.toLoggableString(), var8);
} else {
this.responseCallback.onFailure(RealCall.this, var8);
}
} finally {
RealCall.this.logEventListener.callEnd(RealCall.this);
RealCall.this.client.dispatcher().finished(this);
Thread.currentThread().setName(oldName);
}
}
这里写自定义目录标题
欢迎使用Markdown编辑器
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
新的改变
我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:
- 全新的界面设计 ,将会带来全新的写作体验;
- 在创作中心设置你喜爱的代码高亮样式,Markdown 将代码片显示选择的高亮样式 进行展示;
- 增加了 图片拖拽 功能,你可以将本地的图片直接拖拽到编辑区域直接展示;
- 全新的 KaTeX数学公式 语法;
- 增加了支持甘特图的mermaid语法1 功能;
- 增加了 多屏幕编辑 Markdown文章功能;
- 增加了 焦点写作模式、预览模式、简洁写作模式、左右区域同步滚轮设置 等功能,功能按钮位于编辑区域与预览区域中间;
- 增加了 检查列表 功能。
功能快捷键
撤销:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜体:Ctrl/Command + I
标题:Ctrl/Command + Shift + H
无序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
检查列表:Ctrl/Command + Shift + C
插入代码:Ctrl/Command + Shift + K
插入链接:Ctrl/Command + Shift + L
插入图片:Ctrl/Command + Shift + G
查找:Ctrl/Command + F
替换:Ctrl/Command + G
合理的创建标题,有助于目录的生成
直接输入1次#,并按下space后,将生成1级标题。
输入2次#,并按下space后,将生成2级标题。
以此类推,我们支持6级标题。有助于使用TOC
语法后生成一个完美的目录。
如何改变文本的样式
强调文本 强调文本
加粗文本 加粗文本
标记文本
删除文本
引用文本
H2O is是液体。
210 运算结果是 1024.
插入链接与图片
链接: link.
图片:
带尺寸的图片:
居中的图片:
居中并且带尺寸的图片:
当然,我们为了让用户更加便捷,我们增加了图片拖拽功能。
如何插入一段漂亮的代码片
去博客设置页面,选择一款你喜欢的代码片高亮样式,下面展示同样高亮的 代码片
.
// An highlighted block
var foo = 'bar';
生成一个适合你的列表
- 项目
- 项目
- 项目
- 项目
- 项目1
- 项目2
- 项目3
- 计划任务