饿了么开源项目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-客户端连接相关推荐

  1. 饿了么开源项目Hermes跨进程架构分析1-服务端注册

    文章目录 1 注册实现 1.1 创建aidl文件 1.2 服务端实现 1.2.1 HermesService 1.2.2 创建Request和Responce 1.2.3 创建单例UserManage ...

  2. IEC61499开源项目FORTE部分源码分析

    一.IEC 61499简介 IEC 61499 作为工业自动化领域分布式控制系统级建模语言的标准,其第一(体系结构).二(软件工具要求).四(兼容文件的规则)部分的第一版于 2005 年正式发布,并在 ...

  3. Unity开源项目2D流体渲染实现分析

    开源项目LiquidEffect渲染分析 项目传送门 实现流程 步骤一 创建刚体 步骤二 降采样与模糊处理 降采样分析 C#部分 顶点着色器 片元着色器 分析 模糊分析 步骤三 Alpha过滤 项目传 ...

  4. 基于eBPF技术的开源项目Kindling之探针架构介绍

    Kindling开源项目是一款基于eBPF技术的云原生可观测性项目.本文将主要介绍探针的具体架构设计. Kindling探针的架构设计理念 Kindling架构设计中有一个很重要的理念:关注点分离(S ...

  5. Python开源项目介绍:网站日志分析工具

    CodingGo技术社区 自由的编程学习平台 日志分析 日志分析在web系统中故障排查.性能分析方面有着非常重要的作用.该工具的侧重点不是通常的PV,UV等展示,而是在指定时间段内提供细粒度(最小分钟 ...

  6. 【开源项目】X-TRACK源码分析

    文章目录 X-TRACK阅读笔记 整体架构 PageManager 问题 页面的分析 StatusBar Startup页面 Dilaplate页面 页面的布局 动画的设置 LiveMap页面 Sys ...

  7. 前端进阶:跟着开源项目学习插件化架构

    一.微内核架构简介 1. 1 微内核的概念 微内核架构(Microkernel Architecture),有时也被称为插件化架构(Plug-in Architecture),是一种面向功能进行拆分的 ...

  8. android开源项目!来一份全面的面试宝典练练手,通用流行框架大全

    前言 今天我给大家再次分享一下,我最近的一些读书的感想,思考起来,确实能够给自己带来一些真实的帮助和启发,希望大家在平时的工作学习中,也能够认清楚学习的一些本质. 如果我们的学习是在不断掌握应对具体工 ...

  9. OpenInfra 基金会积极推动开源项目在中国市场的发展与应用

    2021年6月2日,OpenInfra基金会(开源基础设施基金会)联合白金成员以线上线下相结合的方式举行了新闻发布会,分享了OpenInfra基金会各个社区的最新进展,以及社区成员对相关技术的广泛应用 ...

最新文章

  1. 安装旧版本插件_iOS 应用降级插件,支持任意版本升降
  2. jdk1.8api中文版下载(帮助文档)
  3. 终止线程的2种方法。标记法和中断
  4. 下拉框联动_058-ajax之三级联动案例分析
  5. 巧用 Img / JavaScript 采集页面数据
  6. Vue第二部分(5):编程式的路由导航和实战案例
  7. Docker实战6 之构建自己的docker镜像
  8. 【字体分享】适合寒露闪屏设计的字体有哪些?
  9. 界面设计配色方案说明图一(含RGB配色表)
  10. 计算机专业春考技能考什么技能,春季高考信息技术考试说明知识技能
  11. 【电脑技术】修改无线网卡MAC地址失败的原因
  12. 南阳oj入门题-奋斗的小蜗牛
  13. Linux第二章:6.Xftp安装教程、使用Xftp进行远程文件传输
  14. pc android 凤凰,应用多开,这才是最适用电脑的安卓—凤凰系统2.0
  15. Java设计模式的一些积累
  16. SQL语句把一个表中的a字段的值赋值到另一个字段b
  17. FM/AM收音机原理
  18. 【编写自己的RTOS】搞定任务调度
  19. Ant构建工具知识概括
  20. Android基础知识——Android SDK Manager详解

热门文章

  1. less命令查看文件内容
  2. Tau PET成像在神经退行性Tau病中的应用—仍然是一个挑战
  3. C语言中select函数的使用
  4. 浅谈等保2.0标准下医院信息化安全问题研究及对策
  5. java学习第13天
  6. 【电脑开机蓝屏怎么解决】
  7. 查看linux线程个数,linux查看cpu个数,线程数及cpu型号
  8. Bad configuration options
  9. 《炉石传说》架构设计赏析(5):卡牌技能的静态数据组织
  10. 计算机技能节活动作文,技能节有感