Hermes框架使用及流程分析

Hermes是Android中的跨进程通信框架,由饿了么出品。主要使用Binder来实现的跨进程通信。跨进程通信在Android中很重要,但是实现起来可以说稍微有些麻烦,尤其在两个进程通信的数据类型很多时,要写的中间文件或者AIDL文件就很多。而Hermes很好的解决了这个问题,完全不用你去写Binder文件或者AIDL文件。由于Hermes是在16年开发的,之后一直没有维护,所以直接使用会报错。估计这也是Hermes一直没有火起来的原因吧,毕竟跨进程通信不了解的同学来说,使用的时候报错就直接抛弃了。报错的问题很好解决,我们进入正题来说。

目录

一、解决Hermes使用时报错的问题

二、Hermes使用

三、Hermes原理分析


一、解决Hermes使用时报错的问题

Hermes源码地址

解决这个错误很简单,我们先把源码下载下来,修改错误,重新打一个包,放在自己的项目中使用就可以了。因为Hermes中的代码还在依赖v7和v4的包,而我司的项目早就适配AndroidX了,所以我直接把Hermes的源码拷贝在新module里,然后打包依赖。

报错主要是因为源码中TypeUtils这个类,我们把这句话注释掉就可以了

二、Hermes使用

我这里以单例为例子来说(假设B进程想要获取A进程某单例的属性值)

首先在清单文件中注册服务

<service android:name=".HermesService$HermesService0"/>

创建接口ISingleton单例类Singleton和

@ClassId("Singleton")
public interface ISingleton {
    @MethodId("setValue")
    void setValue(String value);

    @MethodId("getValue")
    String getValue();
}


@ClassId("Singleton")
public class Singleton {
    private static Singleton sInstance;
    private String value;

    private Singleton(){}

    public static Singleton getInstance(){
        if(sInstance==null){
            synchronized (Singleton.class){
                if(sInstance==null){
                    sInstance = new Singleton();
                }
            }
        }
        return sInstance;
    }

    @MethodId("setValue")
    public void setValue(String value) {
        this.value = value;
    }

    @MethodId("getValue")
    public String getValue() {
        return value;
    }
}

有一点需要说明:ISingleton和Singleton两个类不一定要有继承关系,当然如果是继承关系的话也不会出错。但是在两个类中ClassId和MethodId要相同

我们从这两个中找到了两个新的东西ClassIdMethodId。顾名思义,ClassId其实就是Hermes来标识此类的一个标记,MethodId是用来标识方法的。这两个类中,ClassId的值相同,对应方法的MethodId相同。

 

创建MainActivity(主进程,相当于进程A),对单例类进行注册

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //注册
        Hermes.register(Singleton.class);
        //给单例的属性值赋值
        Singleton.getInstance().setValue("gzc");
    }

    /**
     * 跳转到SecondActivity(子进程,相当于进程B)
     * @param view
     */
    public void jumpToSecond(View view) {
        startActivity(new Intent(this,SecondActivity.class));
    }
}

一定不要忘了注册这一步,只要某个类想在两个进程中通信,就必须要注册

 

创建SecondActivity(子进程,相当于进程B)

public class SecondActivity extends AppCompatActivity {
    ISingleton singleton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        //连接成功的监听
        Hermes.setHermesListener(new HermesListener() {
            @Override
            public void onHermesConnected(Class<? extends HermesService> service) {
                Log.d("SecondActivity","链接成功");
                singleton = Hermes.getInstance(ISingleton.class);
                Log.d("SecondActivity","value:"+singleton.getValue());
            }
        });
        //连接
        Hermes.connect(getApplicationContext());
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Hermes.disconnect(getApplicationContext());
    }
}

首先,先进行连接操作,成功后Hermes调用getInstance方法,参数为ISingleton.class。此时返回的为ISingleton对象,这时候调用getValue方法,获取的就是主进程Singleton类中value值。最后不要忘了disconnect。

Hermes除了getInstance方法外,还有newInstance和getUtilityClass。newInstance的通信类型为普通类;getUtilityClass的通信类型为普通类中的静态方法。在我看来,这两种平时可能应用的少一点,如果使用newInstance创建的话,相当于在A进程中创建了对象,和直接在B进程中创建没什么区别吧;而使用getUtilityClass,并不会在A进程中创建对象,我们可以在源码中可以看到,invokeMethod方法都是空的,关键是调用方法,获取A进程中静态方法的值。

三、Hermes原理分析

如果大家想看Hermes源码的话,建议先学习Binder相关的只是,知道怎么使用Binder进行跨进程通信。

虽然Hermes的源码看着不少,但是顺着使用的代码来捋顺的话,还是不难的。从源码上来看,B进程(子进程或其他进程)并没有做特殊的工作,它的工作只有两个:发送具体的指令和接收A进程(主进程或自己App的进程)的通信数据。我们画一张流程图来了解一下(以getInstance为例,假设ClassId和MethodId已经按上面的介绍添加完成):

 

Hermes的确不难,静下心来仔细阅读源码都会明白其中的道理的。如果有什么问题欢迎在留言区留言,我每天都会看的,哈哈

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值