Compont源码分析
使用说明
1. 实现Component接口创建子类
@SharedConst
public class MsgComponent implements Component {
private static final String FUNCTION_1 = "showToast";
private static final String FUNCTION_2 = "showToastAsync";
@Override
public boolean onCall(RealCaller caller) {
String actionName = caller.actionName();
if (FUNCTION_1.equals(actionName)) {
Context context = caller.getParamValue("context");
if (context != null) {
Toast.makeText(context, "有内鬼,终止交易!", Toast.LENGTH_SHORT).show();
}
return false;
} else if (FUNCTION_2.equals(actionName)) {
ComponentResult result = new ComponentResult();
result.addData("result", "有内鬼,终止交易!");
ComponentClient.sendResult(caller.getCallId(), result);
return true;
}
return false;
}
}
实现Component的public boolean onCall(RealCaller caller)方法.
返回值表示是否异步,true表示异步.
2. 定义方法名,并在onCall中区分对应的实现
其中,异步方法的结果要通过public static void sendResult(String callId, ComponentResult result)返回.
原理
该方法最终会根据传入的callId找到对应的RealCaller,并调用setResultForWaiting(ComponentResult result)方法,将结果返回.
static void sendResult(String callId, ComponentResult result) {
RealCaller caller = ComponentMonitor.getCallerById(callId);
if (caller != null) {
if (caller.markFinished()) {
if (result == null) {
result = ComponentResult.defaultNullResult();
}
caller.setResultForWaiting(result);
}
}
}
3. 同步调用
ComponentResult rst = ComponentClient.obtainBuilder("MsgComponent")
.setActionName("showToast")
.addParam("param_from", "[同步]")
.build()
.call();
Toast.makeText(getContext(), "" + rst.getData().get("result"), Toast.LENGTH_SHORT).show();
4. 异步调用
ComponentClient.obtainBuilder("MsgComponent")
.setActionName("showToastAsync")
.addParam("param_from", "[异步]")
.build()
.callAsync(new ComponentCallback() {
@Override
public void onResult(Caller caller, ComponentResult result) {
AppExecutors.getInstance().mainThread().execute(new Runnable() {
@Override
public void run() {
Toast.makeText(getContext(), "" + result.getData().get("result"), Toast.LENGTH_SHORT).show();
}
});
}
});
源码分析
3个Interceptor类
-
VerifyInterceptor:对Component做校验; -
WaitForResultInterceptor:对结果做等待;这里会对结果加锁. -
CallServiceInterceptor:真实的调用;
CallServiceInterceptor中会将Component请求封装在CallServiceRunnable,之后通过调用Component的onCall方法,做真正的请求.
onCall里就是我们在Component子类中的具体实现.
1个Future模式
onCall的返回值,表明是否为异步调用.如果为true,表示异步获取结果;否则,同步.
如果在同步调用时,没有直接返回结果,会自动返回默认结果.
static class CallServiceRunnable implements Runnable {
@Override
public void run() {
boolean callbackDelay = component.onCall(mCaller);
//如果是同步回调接口,并且没有主动发送结果。
if (!callbackDelay && !mCaller.isFinished()) {
setResult(ComponentResult.defaultNullResult());
}
}
}
异步必须在我们自定义的Component子类中手动调用ComponentClient的sendResult方法,将结果返回.
ComponentResult result = new ComponentResult();
result.addData("result", "有内鬼,终止交易!");
ComponentClient.sendResult(caller.getCallId(), result);
这里sendResult方法中,会将在WaitForResultInterceptor中加的锁解开,从而允许结果返回.
static void sendResult(String callId, ComponentResult result) {
RealCaller caller = ComponentMonitor.getCallerById(callId);
if (caller != null) {
if (caller.markFinished()) {
if (result == null) {
result = ComponentResult.defaultNullResult();
}
caller.setResultForWaiting(result);
}
}
}
caller.markFinished()中会将锁解开,并通知等待线程,从而继续将结果返回.
这个过程非常像J.U.C中的Future模式,即先返回一个对象,这个对象会等待真正的结果返回.









网友评论