源码分析
核心类
//typecenter对象专门用于缓存
private static final TypeCenter TYPE_CENTER = TypeCenter.getInstance();
//Channel对象用于绑定和解绑跨进程的service
private static final Channel CHANNEL = Channel.getInstance();
//发送各种实体对象的基类
com.library.hermes.sender.Sender
//动态代理实现类,通过反射调用方法
com.library.hermes.internal.HermesInvocationHandler
//返回的结果对象
com.library.hermes.internal.Reply
//发送的结果对象
com.library.hermes.internal.Mail
//各种包装类
com.library.hermes.wrapper
init(Context);
//初始化获得当前app的application对象
public void init(Context context) {
if (sContext != null) {
return;
}
sContext = context.getApplicationContext();
}
register();
当前方法在主进程中注册
/**
* 如果方法的返回类型与方法的接口返回类型一致,则不不需要在本地进程中注册类!
* 但是,如果方法的返回类型与方法的返回类型不完全相同,则应该注册该方法。
*
* @param clazz
*/
public static void register(Class<?> clazz) {
//检查是否有context对象,没有则抛出异常
checkInit();
//注册该class,跟踪到TypeCenter.register(Class)方法
//该方法主要是缓存当前的class和class下的method
TYPE_CENTER.register(clazz);
}
//检查是否传递进来了context对象
private static void checkInit() {
if (sContext == null) {
throw new IllegalStateException("Hermes has not been initialized.");
}
}
onnectApp();
当前方法在子进程中调用,用于绑定一个跨进程服务
/**
* 其他进程需要调用该方法进行连接操作
*
* @param context 当前进程的context
* @param packageName 主进程的包名
* @param service 主进程中注册的service,这个service继承HermesService,需要在清单文件中注册
**/
public static void connectApp(Context context, String packageName, Class<? extends HermesService> service) {
//如果两个进程在同一个app中看,则这里不会再初始化;
//如果两个进程再不同的app中,则这里的connectApp()方法依然会去调用init(context)方法
init(context);
//进行绑定操作,进入绑定操作,看Channel->bind
CHANNEL.bind(context.getApplicationContext(), packageName, service);
}
Channel.bind(Context,String,CLass<? extends HermesService>)
/**
* 子进程中去绑定
*
* @param context 当前进程的context对象
* @param packageName 主进程的包名,如果是同一个进程,则不需要传递。如果是不同的app则需要传递
* @param service 注册的service
*/
public void bind(Context context, String packageName, Class<? extends HermesService> service) {
//跨进程连接对象,实现了ServiceConnection接口
HermesServiceConnection connection;
//同步锁
synchronized (this) {
//获得绑定状态,判断当前service是否已经绑定
if (getBound(service)) {
//如果已经绑定了则不需要重复操作
return;
}
//判断当前service是否在绑定中状态
Boolean binding = mBindings.get(service);
if (binding != null && binding) {
//如果已经在绑定中了,则也不需要重复操作
return;
}
//没有缓存到绑定中,则需要进行缓存,这里表示该service正在进行绑定
mBindings.put(service, true);
//new一个跨进程连接对象
connection = new HermesServiceConnection(service);
//将连接对象添加缓存
mHermesServiceConnections.put(service, connection);
}
//绑定服务,不同app,需要指定包名
Intent intent;
if (TextUtils.isEmpty(packageName)) {
intent = new Intent(context, service);
} else {
intent =