本文介绍了Android跨进程通信的原理,并对Hermes的源码进行分析。
先简单总结下:Hermes也是通过AIDL的方式来最终实现跨进程通信,通信的内容是Gson。其中用到的了动态代理技术。
后面再详细分析下为什么要用到动态代理
手动创建IInterface类
如何创建AIDL文件本文就不在讲了,感兴趣的可以看我之前的文章:Android Binder 机制分析(一)
代理
什么是代理
代理就是客户类不再直接和委托类打交道, 而是通过一个中间层来访问, 这个中间层就是代理。为啥要这样呢, 是因为使用代理有两个优势:
- 1.可以隐藏委托类的实现
- 2.可以实现客户与委托类之间的解耦, 在不修改委托类代码的情况下能够做一些额外的处理
静态代理
接口:public interface HelloService {
String sayHello(String content);
}
接口实现类
public class HelloServiceImpl implements HelloService { |
代理类
public class HelloServiceProxy implements HelloService { |
这里的代理类其实也满足了一个面向对象的设计原则,即组合优先于集成。
动态代理
Java动态代理是一种在运行时创建代理类的方法。它可以在不修改源代码的情况下,在程序运行期间为接口创建代理类。它基于 Java 反射机制实现。
动态代理是一种很有用的工具,可以帮助您在不更改目标对象代码的情况下对其进行包装。
动态代理是为接口创建代理类,所以要提前定义一个接口:public interface HelloService {
String sayHello(String content);
}
HelloServiceImpl实现类public class HelloServiceImpl implements HelloService {
public String sayHello(String content) {
return "hello " + content;
}
}
使用InvocationHandler,实现动态代理public class MyInvocationHandler implements InvocationHandler {
// 真实对象
private Object obj;
public MyInvocationHandler(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before invoke......");
// 此处通过反射,调用真实对象的相关方法
Object result = method.invoke(obj, args);
System.out.println("after invoke......");
return result;
}
}
如何使用:public class DynamicProxyTest {
public static void main(String[] args) {
String content = "dynamic proxy";
// 创建真实实现对象
HelloService helloService = new HelloServiceImpl();
// 创建调用器
InvocationHandler handler = new MyInvocationHandler(helloService);
// 创建代理实例
Object proxy = Proxy.newProxyInstance(helloService.getClass().getClassLoader(), helloService.getClass()
.getInterfaces(), handler);
System.out.println("代理类名称:" + proxy.getClass().getName());
System.out.println("代理类接口:" + proxy.getClass().getInterfaces()[0].getName());
// 类型转换
HelloService proxyService = (HelloService) proxy;
// 执行代理逻辑
System.out.println(proxyService.sayHello(content));
}
}
输出:代理类名称:com.sun.proxy.$Proxy0
代理类接口:com.sankuai.meituan.zcm.depot.proxy.HelloService
before invoke......
after invoke......
hello dynamic proxy
动态代理分析
public final class $Proxy0 extends Proxy implements HelloService { |
怎么拿到动态生成的代理class
import sun.misc.ProxyGenerator; |
然后运行下面的代码就可以:// 保存JDK动态代理生成的代理类,类名保存为 UserServiceProxy
ProxyUtils.generateClassFile(userServiceImpl.getClass(), "UserServiceProxy");
本文链接:http://agehua.github.io/2023/10/26/cross-process-bridge/