饿了么开源项目Hermes跨进程架构分析2-客户端连接
饿了么开源项目Hermes跨进程架构分析1-服务端注册
饿了么开源项目Hermes跨进程架构分析2-客户端连接
文章目录
- 2客户端连接
- 2.1 SecondActivity
- 2.2 Hermes
- 2.3 ServiceConnectionManager
- 2.4 HermesService
2客户端连接
2.1 SecondActivity
SecondActivity的onCreate方法中进行连接,HermesService就是需要连接的Service,如下:
@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_second);Hermes.getDefault().connect(this, HermesService.class);}
SecondActivity开启另一个进程,在AndroidManifest文件中配置如下:
<activity android:name=".SecondActivity"android:process=":s"/>
2.2 Hermes
public class Hermes {//得到对象public static final int TYPE_NEW = 0;//得到单例public static final int TYPE_GET = 1;private static final Hermes ourInstance = new Hermes();private TypeCenter typeCenter;private ServiceConnectionManager serviceConnectionManager;Gson GSON = new Gson();public static Hermes getDefault() {return ourInstance;}private Context sContext;private Hermes() {serviceConnectionManager = ServiceConnectionManager.getInstance();typeCenter = TypeCenter.getInstance();}//------------------------------A进程----------------------------------------------------------------public void register(Class<?> clazz) {//保存 到另外一个单例地方typeCenter.register(clazz);}//------------------------------B进程----------------------------------------------------------------public void connect(Context context, Class<? extends HermesService> service) {connectApp(context, null, service);}public void init(Context context) {sContext = context.getApplicationContext();}public void connectApp(Context context, String packageName, Class<? extends HermesService> service) {init(context); // 注释1serviceConnectionManager.bind(context.getApplicationContext(), packageName, service);}//主要防止方法重载 单例对象 是不需要public <T> T getInstance(Class<T> clazz, Object... parameters) {//Class<T> clazz, Object... parameters ====》 Request ----->ResponceResponce responce = sendRequest(HermesService.class, clazz, null, parameters);
// responce ---》UserManager 不需要 还原 客户端进程压根 UserManagerreturn getProxy(HermesService.class, clazz);}private <T> T getProxy(Class<? extends HermesService> service, Class clazz) {ClassLoader classLoader = service.getClassLoader();T proxy = (T) Proxy.newProxyInstance(classLoader, new Class<?>[]{clazz}, new HermesInvocationHandler(service, clazz));return proxy;}private <T> Responce sendRequest(Class<HermesService> hermesServiceClass, Class<T> clazz, Method method, Object[] parameters) {RequestBean requestBean = new RequestBean();String className = null;if (clazz.getAnnotation(ClassId.class) == null) {// 当requestBean.setClassName(clazz.getName());requestBean.setResultClassName(clazz.getName());} else {// 返回类型的全类名requestBean.setClassName(clazz.getAnnotation(ClassId.class).value());requestBean.setResultClassName(clazz.getAnnotation(ClassId.class).value());}if (method != null) {// 方法名 统一 传 方法名+参数名 getInstance(java.lang.String)requestBean.setMethodName(TypeUtils.getMethodId(method));}
//fastjson ---》 GSONRequestParameter[] requestParameters = null;if (parameters != null && parameters.length > 0) {requestParameters = new RequestParameter[parameters.length];for (int i = 0; i < parameters.length; i++) {Object parameter = parameters[i];String parameterClassName = parameter.getClass().getName();String parameterValue = GSON.toJson(parameter);RequestParameter requestParameter = new RequestParameter(parameterClassName, parameterValue);requestParameters[i] = requestParameter;}}if (requestParameters != null) {requestBean.setRequestParameter(requestParameters);}// 请求获取单例 ----》对象 ----------》调用对象的方法Request request = new Request(GSON.toJson(requestBean), TYPE_GET);return serviceConnectionManager.request(hermesServiceClass, request);}public <T> Responce sendObjectRequest(Class<HermesService> hermesServiceClass, Class<T> clazz, Method method, Object[] parameters) {RequestBean requestBean = new RequestBean();String className = null;if (clazz.getAnnotation(ClassId.class) == null) {// 当requestBean.setClassName(clazz.getName());requestBean.setResultClassName(clazz.getName());} else {// 返回类型的全类名requestBean.setClassName(clazz.getAnnotation(ClassId.class).value());requestBean.setResultClassName(clazz.getAnnotation(ClassId.class).value());}if (method != null) {// 方法名 统一 传 方法名+参数名 getInstance(java.lang.String)requestBean.setMethodName(TypeUtils.getMethodId(method));}
//fastjson ---》 GSONRequestParameter[] requestParameters = null;if (parameters != null && parameters.length > 0) {requestParameters = new RequestParameter[parameters.length];for (int i = 0; i < parameters.length; i++) {Object parameter = parameters[i];String parameterClassName = parameter.getClass().getName();String parameterValue = GSON.toJson(parameter);RequestParameter requestParameter = new RequestParameter(parameterClassName, parameterValue);requestParameters[i] = requestParameter;}}if (requestParameters != null) {requestBean.setRequestParameter(requestParameters);}// 请求获取单例 ----》对象 ----------》调用对象的方法Request request = new Request(GSON.toJson(requestBean), TYPE_NEW);return serviceConnectionManager.request(hermesServiceClass, request);}
}
注释1:客户端连接的时候,因为另起了一个进程,所有需要获取客户端的ApplicationContext。
2.3 ServiceConnectionManager
ServiceConnectionManager用于管理Service连接
public class ServiceConnectionManager {private static final ServiceConnectionManager ourInstance = new ServiceConnectionManager();// Class 对应的Binder 对象private final ConcurrentHashMap<Class<? extends HermesService>, MyEventBusService> mHermesServices =new ConcurrentHashMap<Class<? extends HermesService>, MyEventBusService>();public static ServiceConnectionManager getInstance() {return ourInstance;}//Class对应的链接对象private final ConcurrentHashMap<Class<? extends HermesService>, HermesServiceConnection> mHermesServiceConnections = new ConcurrentHashMap<Class<? extends HermesService>, HermesServiceConnection>();private ServiceConnectionManager() {}//绑定Servicepublic void bind(Context context, String packageName, Class<? extends HermesService> service) {HermesServiceConnection connection = new HermesServiceConnection(service);mHermesServiceConnections.put(service, connection);Intent intent ;if (TextUtils.isEmpty(packageName)) {intent = new Intent(context, service);} else {intent = new Intent();intent.setClassName(packageName, service.getName());}context.bindService(intent, connection, Context.BIND_AUTO_CREATE);}public Responce request(Class<HermesService> hermesServiceClass, Request request) {//从缓存中获取binder代理对象,发送请求MyEventBusService eventBusService = mHermesServices.get(hermesServiceClass);if (eventBusService != null) {try {Responce responce= eventBusService.send(request);return responce;} catch (RemoteException e) {e.printStackTrace();}}return null;}// 接受远端的binder 对象 进程B就可以了通过Binder对象去操作 服务端的 方法private class HermesServiceConnection implements ServiceConnection {private Class<? extends HermesService> mClass;HermesServiceConnection(Class<? extends HermesService> service) {mClass = service;}@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {MyEventBusService hermesService = MyEventBusService.Stub.asInterface(service);mHermesServices.put(mClass, hermesService);}@Overridepublic void onServiceDisconnected(ComponentName name) {mHermesServices.remove(mClass);}}
}
2.4 HermesService
public class HermesService extends Service {@Nullable@Overridepublic IBinder onBind(Intent intent) {return mBinder;}private MyEventBusService.Stub mBinder = new MyEventBusService.Stub() {@Overridepublic Responce send(Request request) throws RemoteException {// 对请求参数进行处理 生成Responce结果返回ResponceMake responceMake = null;switch (request.getType()) { //根据不同的类型,产生不同的策略case Hermes.TYPE_GET://获取单例responceMake = new InstanceResponceMake();break;case Hermes.TYPE_NEW:responceMake = new ObjectResponceMake();break;}return responceMake.makeResponce(request);}};
}
饿了么开源项目Hermes跨进程架构分析2-客户端连接相关推荐
- 饿了么开源项目Hermes跨进程架构分析1-服务端注册
文章目录 1 注册实现 1.1 创建aidl文件 1.2 服务端实现 1.2.1 HermesService 1.2.2 创建Request和Responce 1.2.3 创建单例UserManage ...
- IEC61499开源项目FORTE部分源码分析
一.IEC 61499简介 IEC 61499 作为工业自动化领域分布式控制系统级建模语言的标准,其第一(体系结构).二(软件工具要求).四(兼容文件的规则)部分的第一版于 2005 年正式发布,并在 ...
- Unity开源项目2D流体渲染实现分析
开源项目LiquidEffect渲染分析 项目传送门 实现流程 步骤一 创建刚体 步骤二 降采样与模糊处理 降采样分析 C#部分 顶点着色器 片元着色器 分析 模糊分析 步骤三 Alpha过滤 项目传 ...
- 基于eBPF技术的开源项目Kindling之探针架构介绍
Kindling开源项目是一款基于eBPF技术的云原生可观测性项目.本文将主要介绍探针的具体架构设计. Kindling探针的架构设计理念 Kindling架构设计中有一个很重要的理念:关注点分离(S ...
- Python开源项目介绍:网站日志分析工具
CodingGo技术社区 自由的编程学习平台 日志分析 日志分析在web系统中故障排查.性能分析方面有着非常重要的作用.该工具的侧重点不是通常的PV,UV等展示,而是在指定时间段内提供细粒度(最小分钟 ...
- 【开源项目】X-TRACK源码分析
文章目录 X-TRACK阅读笔记 整体架构 PageManager 问题 页面的分析 StatusBar Startup页面 Dilaplate页面 页面的布局 动画的设置 LiveMap页面 Sys ...
- 前端进阶:跟着开源项目学习插件化架构
一.微内核架构简介 1. 1 微内核的概念 微内核架构(Microkernel Architecture),有时也被称为插件化架构(Plug-in Architecture),是一种面向功能进行拆分的 ...
- android开源项目!来一份全面的面试宝典练练手,通用流行框架大全
前言 今天我给大家再次分享一下,我最近的一些读书的感想,思考起来,确实能够给自己带来一些真实的帮助和启发,希望大家在平时的工作学习中,也能够认清楚学习的一些本质. 如果我们的学习是在不断掌握应对具体工 ...
- OpenInfra 基金会积极推动开源项目在中国市场的发展与应用
2021年6月2日,OpenInfra基金会(开源基础设施基金会)联合白金成员以线上线下相结合的方式举行了新闻发布会,分享了OpenInfra基金会各个社区的最新进展,以及社区成员对相关技术的广泛应用 ...
最新文章
- 安装旧版本插件_iOS 应用降级插件,支持任意版本升降
- jdk1.8api中文版下载(帮助文档)
- 终止线程的2种方法。标记法和中断
- 下拉框联动_058-ajax之三级联动案例分析
- 巧用 Img / JavaScript 采集页面数据
- Vue第二部分(5):编程式的路由导航和实战案例
- Docker实战6 之构建自己的docker镜像
- 【字体分享】适合寒露闪屏设计的字体有哪些?
- 界面设计配色方案说明图一(含RGB配色表)
- 计算机专业春考技能考什么技能,春季高考信息技术考试说明知识技能
- 【电脑技术】修改无线网卡MAC地址失败的原因
- 南阳oj入门题-奋斗的小蜗牛
- Linux第二章:6.Xftp安装教程、使用Xftp进行远程文件传输
- pc android 凤凰,应用多开,这才是最适用电脑的安卓—凤凰系统2.0
- Java设计模式的一些积累
- SQL语句把一个表中的a字段的值赋值到另一个字段b
- FM/AM收音机原理
- 【编写自己的RTOS】搞定任务调度
- Ant构建工具知识概括
- Android基础知识——Android SDK Manager详解