Hermes——跨进程通信(IPC)框架,使用介绍

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/yehui928186846/article/details/99677022

概述

Hermes的源码地址

Hermes的Demo地址

  1. Android进程间通信IPC框架
  2. 像调用本地函数一样调用其他进程的函数
  3. 在本地进程创建其他进程类的对象
  4. 在本进程获取其他进程的单例
  5. 在本进程使用其他进程的工具类
  6. 支持进程间函数回调,调用其他进程函数的时候可以传入回调函数,让其他进程回调本进程的方法
  7. 自带内存优化,内置两个垃圾回收器,地进程在远端进程创建的实例和本地进程传给远端进程的回调接口会被自动回收。

基本使用

compile 'xiaofei.library:hermes:0.7.0'

    
    
  • 1

两个进程共享一个对象单例

//在进程A中,类使用注解标记该类的id
@ClassId(“Singleton”)
public class Singleton {
    //属性
    private volatile String mData;
<span class="token comment">//实现单例,代码省略</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> Singleton <span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token comment">//方法使用注解标记该方法的id</span>
<span class="token annotation punctuation">@MethodId</span><span class="token punctuation">(</span>“setData”<span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setData</span><span class="token punctuation">(</span>String data<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    mData <span class="token operator">=</span> data<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token annotation punctuation">@MethodId</span><span class="token punctuation">(</span>“getData”<span class="token punctuation">)</span>
<span class="token keyword">public</span> String <span class="token function">getData</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> mData<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

进程B要访问在进程A中的Singleton对象,如下:

//在进程B中,自定义接口
//该接口指定与Singleton的注解的classid一致
@ClassId(“Singleton”)
public interface ISingleton {
	//方法id与Singleton的注解的methodid一致
    @MethodId(“setData”)
    void setData(String data);
<span class="token annotation punctuation">@MethodId</span><span class="token punctuation">(</span>“getData”<span class="token punctuation">)</span>
String <span class="token function">getData</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
//使用如下:
//获得Singleton对象
ISingleton singleton = Hermes.getInstance(ISingleton.class);
//调用方法
singleton.setData(“Hello, Hermes!);
//调用方法
Log.v(TAG, singleton.getData());

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

在其他进程调用主进程的函数

Hermes支持任意进程之间的函数调用

AndroidManifest.xml

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

 
 
  • 1

主进程初始化Hermes

//在给其他进程提供函数的进程中,使用Hermes.init(Context)初始化
Hermes.init(Context);

 
 
  • 1
  • 2

子进程连接Hermes

//子进程链接Hermes后才可以使用Hermes的服务
//在Application.OnCreate()或Activity.OnCreate()
Hermes.connect(Context)
 
 
  • 1
  • 2
  • 3

查看通信的进程是否还活着

Hermes.isConnected()

 
 
  • 1

事先注册被调用的类

//进程A中,被进程B调用的类需要事先注册
//如果类上面没有加上注解,那么注册就不是必须的,Hermes会通过类名进行反射查找相应的类
//有两种注册类的API:
Hermes.register(Class<?>)
Hermes.register(Object)
Hermes.register(object)等价于Hermes.register(object.getClass())

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

设置连接监听

//在连接之前给Hermes设置监听器
Hermes.setHermesListener(new HermesListener() {
    @Override
    public void onHermesConnected(Class<? extends HermesService> service) {
        //连接成功,首先获取单例
       IUserInfo iUserinfo = Hermes.getInstance(IUserInfo.class);
        //通过单例获取UserInfo
       String name = iUserinfo.getUserName();
    }
});
//连接Hermes服务
Hermes.connect(context);

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

连接Hermes服务

Hermes.connect(context);//需要连接服务才能得到其他进程的实例

 
 
  • 1

断开Hermes服务

Hermes.disconnect(context);

 
 
  • 1

创建实例

//进程B中,创建进程A中的实例有三种方法:
Hermes.newInstance(Class,Object…)
Hermes.getInstance(Class,Object…)
Hermes.getUtilityClass(Class)

 
 
  • 1
  • 2
  • 3
  • 4
Hermes.newInstance(Class,Object…)
  1. 在进程A中创建指定类的实例,并将引用返回给进程B。

  2. 函数的第二个参数将传给指定类的对应的构造器。

  3. 在进程B中,调用Hermes.newInstance(ILoadingTask.class, “xxx”, true)得到LoadingTask实例。

  4. 注意:该实例不是单例,该实例为当前线程所拥有的实例。

@ClassId(“LoadingTask”)
public class LoadingTask {
<span class="token keyword">public</span> <span class="token function">LoadingTask</span><span class="token punctuation">(</span>String path<span class="token punctuation">,</span> <span class="token keyword">boolean</span> showImmediately<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//...</span>
<span class="token punctuation">}</span>

<span class="token annotation punctuation">@MethodId</span><span class="token punctuation">(</span>“start”<span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//...</span>
<span class="token punctuation">}</span>

}

@ClassId(“LoadingTask”)
public interface ILoadingTask {
@MethodId(“start”)
void start();
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
Hermes.getInstance(Class , Object…)
  1. 在进程A中通过指定类的getInstance()方法创建实例,并将引用返回给进程B。
  2. 第二个参数将传给对应的getInstance()方法。
  3. 该函数适合获取单例,这样进程A和进程B就使用同一个单例。
  4. 进程B中,调用Hermes.getInstance(IBitmapWrapper.class, “XXX”)将得到BitmapWrapper的实例。
  5. 进程B中,调用Hermes.getInstance(IBitmapWrapper.class, 100)将得到BitmapWrapper的实例。
@ClassId(“BitmapWrapper”)
public class BitmapWrapper {
<span class="token annotation punctuation">@GetInstance</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> BitmapWrapper <span class="token function">getInstance</span><span class="token punctuation">(</span>String path<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//这里可以写成单例,两个进程可以获得当前这个实例</span>
<span class="token punctuation">}</span>

<span class="token annotation punctuation">@GetInstance</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> BitmapWrapper <span class="token function">getInstance</span><span class="token punctuation">(</span><span class="token keyword">int</span> label<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//...</span>
<span class="token punctuation">}</span>

<span class="token annotation punctuation">@MethodId</span><span class="token punctuation">(</span>“show”<span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">show</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//...</span>
<span class="token punctuation">}</span>

}

@ClassId(“BitmapWrapper”)
public interface IBitmapWrapper {

<span class="token annotation punctuation">@MethodId</span><span class="token punctuation">(</span>“show”<span class="token punctuation">)</span>
<span class="token keyword">void</span> <span class="token function">show</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
Hermes.getUtilityClass(Class )
  1. 获取进程A的工具类。
  2. 这种做法在插件开发中很有用。
  3. 主app和插件app存在不同的进程中,为了维护方便,应该使用统一的工具类。
  4. 插件app可以通过这个方法获取主app的工具类。
@ClassId(“Maths”)
public class Maths {
<span class="token annotation punctuation">@MethodId</span><span class="token punctuation">(</span>“plus”<span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token function">plus</span><span class="token punctuation">(</span><span class="token keyword">int</span> a<span class="token punctuation">,</span> <span class="token keyword">int</span> b<span class="token punctuation">)</span> <span class="token punctuation">{</span>
   <span class="token comment">//模拟加法</span>
<span class="token punctuation">}</span>

<span class="token annotation punctuation">@MethodId</span><span class="token punctuation">(</span>“minus”<span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">int</span> <span class="token function">minus</span><span class="token punctuation">(</span><span class="token keyword">int</span> a<span class="token punctuation">,</span> <span class="token keyword">int</span> b<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment">//模拟减法</span>
<span class="token punctuation">}</span>

}

@ClassId(“Maths”)
public interface IMaths {

<span class="token annotation punctuation">@MethodId</span><span class="token punctuation">(</span>“plus”<span class="token punctuation">)</span>
<span class="token keyword">int</span> <span class="token function">plus</span><span class="token punctuation">(</span><span class="token keyword">int</span> a<span class="token punctuation">,</span> <span class="token keyword">int</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@MethodId</span><span class="token punctuation">(</span>“minus”<span class="token punctuation">)</span>
<span class="token keyword">int</span> <span class="token function">minus</span><span class="token punctuation">(</span><span class="token keyword">int</span> a<span class="token punctuation">,</span> <span class="token keyword">int</span> b<span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

进程B中,使用下面代码使用进程A的工具类

IMaths maths = Hermes.getUtilityClass(IMaths.class);
int sum = maths.plus(3, 5);
int diff = maths.minus(3, 5);

 
 
  • 1
  • 2
  • 3
其他注解的使用
//@WithinProcess//不让其他进程访问
@ClassId("HermesOtherBean")
public class HermesOtherBean {
<span class="token comment">//@WeakRef:持有当前回调的弱引用</span>
<span class="token comment">//@Background:不让回调函数运行在主线程</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">customBackMethod</span><span class="token punctuation">(</span>HermesMethodBean hermesMethodBean<span class="token punctuation">,</span> IHermesOtherListener iHermesOtherListener<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">if</span> <span class="token punctuation">(</span>hermesMethodBean <span class="token operator">!=</span> null<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        iHermesOtherListener<span class="token punctuation">.</span><span class="token function">getVoid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        iHermesOtherListener<span class="token punctuation">.</span><span class="token function">setInteger</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">int</span> i <span class="token operator">=</span> iHermesOtherListener<span class="token punctuation">.</span><span class="token function">getBackInteger</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        iHermesOtherListener<span class="token punctuation">.</span><span class="token function">setString</span><span class="token punctuation">(</span><span class="token string">"customBackMethod"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        String str <span class="token operator">=</span> iHermesOtherListener<span class="token punctuation">.</span><span class="token function">getBackString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        iHermesOtherListener<span class="token punctuation">.</span><span class="token function">setHermesMethod</span><span class="token punctuation">(</span>hermesMethodBean<span class="token punctuation">)</span><span class="token punctuation">;</span>
        Log<span class="token punctuation">.</span><span class="token function">i</span><span class="token punctuation">(</span><span class="token string">"appjson"</span><span class="token punctuation">,</span> <span class="token string">"getbackInteger:"</span> <span class="token operator">+</span> i <span class="token operator">+</span> <span class="token string">";getBackString:"</span> <span class="token operator">+</span> str<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
@ClassId("IHermesOtherListener")
public interface IHermesOtherListener {
<span class="token keyword">void</span> <span class="token function">getVoid</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">getBackInteger</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">void</span> <span class="token function">setInteger</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span>

String <span class="token function">getBackString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">void</span> <span class="token function">setString</span><span class="token punctuation">(</span>String str<span class="token punctuation">)</span><span class="token punctuation">;</span>

HermesMethodBean <span class="token function">getHermesMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token keyword">void</span> <span class="token function">setHermesMethod</span><span class="token punctuation">(</span>HermesMethodBean hermesMethod<span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
@ClassId("HermesOtherBean")
public interface IHermesOtherBean {
<span class="token comment">//@WeakRef:持有当前回调的弱引用</span>
<span class="token comment">//@Background:不让回调函数运行在主线程</span>
<span class="token keyword">void</span> <span class="token function">customBackMethod</span><span class="token punctuation">(</span>HermesMethodBean hermesMethodBean<span class="token punctuation">,</span> <span class="token annotation punctuation">@WeakRef</span> <span class="token annotation punctuation">@Background</span> IHermesOtherListener iHermesOtherListener<span class="token punctuation">)</span><span class="token punctuation">;</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
public class HermesOtherService extends Service {
    public HermesMethodBean hermesMethodBean = new HermesMethodBean(1, "a", 1D);
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">onCreate</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">onCreate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//在连接之前给Hermes设置监听器</span>
    Hermes<span class="token punctuation">.</span><span class="token function">setHermesListener</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">HermesListener</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token annotation punctuation">@Override</span>
        <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">onHermesConnected</span><span class="token punctuation">(</span>Class<span class="token operator">&lt;</span><span class="token operator">?</span> <span class="token keyword">extends</span> <span class="token class-name">HermesService</span><span class="token operator">&gt;</span> service<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token comment">//连接成功,首先获取单例</span>
            <span class="token keyword">try</span> <span class="token punctuation">{</span>
                <span class="token comment">//静态方法没有限制,这里不清楚原因需要先调用getUtilityClass在调用newInstance才能正常使用</span>
                Hermes<span class="token punctuation">.</span><span class="token function">getUtilityClass</span><span class="token punctuation">(</span>IHermesOtherBean<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token comment">//如果是new的有限制</span>
                IHermesOtherBean iHermesOtherBeanNew <span class="token operator">=</span> Hermes<span class="token punctuation">.</span><span class="token function">newInstance</span><span class="token punctuation">(</span>IHermesOtherBean<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">if</span> <span class="token punctuation">(</span>iHermesOtherBeanNew <span class="token operator">==</span> null<span class="token punctuation">)</span>
                    Log<span class="token punctuation">.</span><span class="token function">i</span><span class="token punctuation">(</span><span class="token string">"appjson"</span><span class="token punctuation">,</span> <span class="token string">"当前IHermesOtherBean==null"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token keyword">else</span> <span class="token punctuation">{</span>
                    <span class="token comment">//这种匿名类是错误的写法</span>

// Log.i(“appjson”, iHermesOtherBean.customMethod(new HermesMethodBean(1, “aaaa”, 1D)));
//这种private的对象也是错误的
// HermesMethodBean hermesMethodBean = new HermesMethodBean(1, “a”, 1D);
// iHermesOtherBean.customMethod(hermesMethodBean);
//必须是非private且不是匿名类的对象
// hermesMethodBean = new HermesMethodBean(1, “a”, 1D);
iHermesOtherBeanNew.customBackMethod(hermesMethodBean, new IHermesOtherListener() {
@Override
public void getVoid() {
Log.i(“appjson”, “getVoid()”);
}

                        <span class="token annotation punctuation">@Override</span>
                        <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">getBackInteger</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                            Log<span class="token punctuation">.</span><span class="token function">i</span><span class="token punctuation">(</span><span class="token string">"appjson"</span><span class="token punctuation">,</span> <span class="token string">"getBackInteger()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                            <span class="token keyword">return</span> <span class="token number">100</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>

                        <span class="token annotation punctuation">@Override</span>
                        <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setInteger</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                            Log<span class="token punctuation">.</span><span class="token function">i</span><span class="token punctuation">(</span><span class="token string">"appjson"</span><span class="token punctuation">,</span> <span class="token string">"setInteger("</span> <span class="token operator">+</span> i <span class="token operator">+</span> <span class="token string">")"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

                        <span class="token punctuation">}</span>

                        <span class="token annotation punctuation">@Override</span>
                        <span class="token keyword">public</span> String <span class="token function">getBackString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                            Log<span class="token punctuation">.</span><span class="token function">i</span><span class="token punctuation">(</span><span class="token string">"appjson"</span><span class="token punctuation">,</span> <span class="token string">"getBackString()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                            <span class="token keyword">return</span> <span class="token string">"getBackString-admin"</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>

                        <span class="token annotation punctuation">@Override</span>
                        <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setString</span><span class="token punctuation">(</span>String str<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                            Log<span class="token punctuation">.</span><span class="token function">i</span><span class="token punctuation">(</span><span class="token string">"appjson"</span><span class="token punctuation">,</span> <span class="token string">"setString("</span> <span class="token operator">+</span> str <span class="token operator">+</span> <span class="token string">")"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>

                        <span class="token annotation punctuation">@Override</span>
                        <span class="token keyword">public</span> HermesMethodBean <span class="token function">getHermesMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                            Log<span class="token punctuation">.</span><span class="token function">i</span><span class="token punctuation">(</span><span class="token string">"appjson"</span><span class="token punctuation">,</span> <span class="token string">"getHermesMethod()"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                            <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">HermesMethodBean</span><span class="token punctuation">(</span><span class="token number">50</span><span class="token punctuation">,</span> <span class="token string">"test"</span><span class="token punctuation">,</span> <span class="token number">99D</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>

                        <span class="token annotation punctuation">@Override</span>
                        <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setHermesMethod</span><span class="token punctuation">(</span>HermesMethodBean hermesMethod<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                            Log<span class="token punctuation">.</span><span class="token function">i</span><span class="token punctuation">(</span><span class="token string">"appjson"</span><span class="token punctuation">,</span> <span class="token string">"setHermesMethod():"</span> <span class="token operator">+</span> hermesMethod<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token punctuation">}</span>
            <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                Log<span class="token punctuation">.</span><span class="token function">i</span><span class="token punctuation">(</span><span class="token string">"appjson"</span><span class="token punctuation">,</span> <span class="token string">"error:"</span> <span class="token operator">+</span> e<span class="token punctuation">.</span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//连接Hermes服务</span>
    Hermes<span class="token punctuation">.</span><span class="token function">connect</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">onDestroy</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">onDestroy</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token comment">//断开Hermes服务</span>
    Hermes<span class="token punctuation">.</span><span class="token function">disconnect</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token annotation punctuation">@Nullable</span>
<span class="token annotation punctuation">@Override</span>
<span class="token keyword">public</span> IBinder <span class="token function">onBind</span><span class="token punctuation">(</span>Intent intent<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> null<span class="token punctuation">;</span>
<span class="token punctuation">}</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

注意事项

  1. 如果两个进程属于两个不同的app(分别叫App A和App B),App A想访问App B的一个类,并且App A的接口和App B的对应类有相同的包名和类名,那么就没有必要在类和接口上加@ClassId注解。

    1. 但是要注意使用ProGuard后类名和包名仍要保持一致。
  2. 如果接口和类里面对应的方法的名字相同,那么也没有必要在方法上加上@MethodId注解。

    1. 但是要注意使用ProGuard后接口内的方法名字必须仍然和类内的对应方法名字相同。
  3. 如果进程A的一个类上面有一个@ClassId注解,这个类在进程B中对应的接口上有一个相同的@ClassId注解,那么进程A在进程B访问这个类之前必须注册这个类。

    1. 否则进程B使用Hermes.newInstance()、Hermes.getInstance()或Hermes.getUtilityClass()时,Hermes在进程A中找不到匹配的类。
    2. 类可以在构造器或者Application.OnCreate()中注册。
    3. 但是如果类和对应的接口上面没有@ClassId注解,但有相同的包名和类名,那么就不需要注册类。
    4. Hermes通过包名和类名匹配类和接口。
    5. 对于接口和类里面的函数,上面的说法仍然适用。
  4. 如果不想让一个类或者函数被其他进程访问,可以在上面加上@WithinProcess注解。

  5. 使用Hermes跨进程调用函数的时候,传入参数的类型可以是原参数类型的子类,但不可以是匿名类和局部类。

    1. 传递的参数不能是匿名类:maths.puls(new A(){});
    2. 传递的参数也不能是private的:private A a=new A(){};
    3. 但是回调函数例外,关于回调函数详见第7点
  6. 如果被调用的函数的参数类型和返回值类型是int、double等基本类型或者String这样的Java通用类型,上面的说法可以很好地解决问题。但如果类型是自定义的类,比如第5点中的自定义类A,并且两个进程分别属于两个不同app,那么你必须在两个app中都定义这个类,且必须保证代码混淆后,两个类仍然有相同的包名和类名。

    1. 不过你可以适用@ClassId和@MethodId注解,这样包名和类名在混淆后不同也不要紧了。
  7. 如果被调用的函数有回调参数,那么函数定义中这个参数必须是一个接口,不能是抽象类。请特别注意回调函数运行的线程。

    1. 如果进程A调用进程B的函数,并且传入一个回调函数供进程B在进程A进行回调操作,那么默认这个回调函数将运行在进程A的主线程(UI线程)。如果你不想让回调函数运行在主线程,那么在接口声明的函数的对应的回调参数之前加上@Background注解。

    2. 如果回调函数有返回值,那么你应该让它运行在后台线程。如果运行在主线程,那么返回值始终为null。

    3. 默认情况下,Hermes持有回调函数的强引用,这个可能会导致内存泄漏。你可以在接口声明的对应回调参数前加上@WeakRef注解,这样Hermes持有的就是回调函数的弱引用。

    4. 如果进程的回调函数被回收了,而对方进程还在调用这个函数(对方进程并不会知道回调函数被回收),这个不会有任何影响,也不会造成崩溃。

    5. 如果回调函数有返回值,那么就返回null。

    6. 如果你使用了@Background和@WeakRef注解,你必须在接口中对应的函数参数前进行添加。

    7. 如果加在其他地方,并不会有任何作用。

    8. @ClassId(“Foo”)
      public class Foo {
          public static void f(int i, Callback callback) {
          }
      }
      

@ClassId(“callback”)
public interface Callback {
void callback();
}

@ClassId(“Foo”)
public interface IFoo {
void f(int i, @WeakRef @Background Callback callback);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 调用函数的时候,任何Context在另一个进程中都会变成对方进程的applicationContext。

  • 数据传输是基于Json的。

  • 使用Hermes的时候,有任何的错误都会使用android.util.Log.e()打出错误日志。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值