我是靠谱客的博主 朴素康乃馨,最近开发中收集的这篇文章主要介绍饿了么开源项目Hermes跨进程架构分析2-客户端连接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,如下:


@Override
protected 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); // 注释1
serviceConnectionManager.bind(context.getApplicationContext(), packageName, service);
}
//主要防止方法重载
单例对象 是不需要
public <T> T getInstance(Class<T> clazz, Object... parameters) {
//Class<T> clazz, Object... parameters
====》
Request
----->Responce
Responce responce = sendRequest(HermesService.class, clazz, null, parameters);
//
responce ---》UserManager
不需要 还原
客户端进程压根 UserManager
return 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
---》
GSON
RequestParameter[] 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
---》
GSON
RequestParameter[] 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() {
}
//绑定Service
public 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;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyEventBusService hermesService = MyEventBusService.Stub.asInterface(service);
mHermesServices.put(mClass, hermesService);
}
@Override
public void onServiceDisconnected(ComponentName name) {
mHermesServices.remove(mClass);
}
}
}

2.4 HermesService

public class HermesService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private MyEventBusService.Stub mBinder = new MyEventBusService.Stub() {
@Override
public 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-客户端连接2客户端连接的全部内容,希望文章能够帮你解决饿了么开源项目Hermes跨进程架构分析2-客户端连接2客户端连接所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部