博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android跨进程组件IPCInvoker用法完全解析
阅读量:6441 次
发布时间:2019-06-23

本文共 12872 字,大约阅读时间需要 42 分钟。

接入IPCInvoker

引入组件库

IPCInvoker组件库已经提交到jcenter上了,可以直接dependencies中配置引用

dependencies {    compile 'cc.suitalk.android:ipc-invoker:1.1.7'}复制代码

定义远端进程Service

这里以PushProcessIPCService为示例,代码如下:

public class PushProcessIPCService extends BaseIPCService {    public static final String PROCESS_NAME = "cc.suitalk.ipcinvoker.sample:push";    @Override    public String getProcessName() {        return PROCESS_NAME;    }}复制代码

在manifest.xml中配置service

复制代码

在项目的Application中setup IPCInvoker

这里需要在你的项目所有需要支持跨进程调用的进程中调用IPCInvoker.setup(Application, IPCInvokerInitDelegate)方法,并在传入的IPCInvokerInitDelegate接口实现中,将该进程需要支持访问的远端进程相应的Service的class添加到IPCInvoker当中,示例如下:

public class IPCInvokerApplication extends Application {    @Override    public void onCreate() {        super.onCreate();        // Initialize IPCInvoker        IPCInvokerBoot.setup(this, new DefaultInitDelegate() {            @Override            public void onAttachServiceInfo(IPCInvokerInitializer initializer) {                initializer.addIPCService(PushProcessIPCService.PROCESS_NAME, PushProcessIPCService.class);            }            @Override            public void onAddTypeTransfer(TypeTransferInitializer initializer) {                super.onAddTypeTransfer(initializer);                initializer.addTypeTransfer(new TestTypeTransfer());            }        });    }}复制代码

到此为止IPCInvoker引入已经完成,可以直接在项目中使用IPCInvoker的跨进程调用接口了.

用IPCInvoker写调用跨进程调用

在使用IPCInvoker编写跨进程调用逻辑前,我们先了解一下IPCInvoker中有哪些接口.

IPCInvoker接口

同步调用接口

@WorkerThreadpublic static 
Bundle invokeSync(@NonNull String process, Bundle data, @NonNull Class
taskClass)复制代码
@WorkerThreadpublic static 
, InputType extends Parcelable, ResultType extends Parcelable> ResultType invokeSync(String process, InputType data, @NonNull Class
taskClass)复制代码

异步调用接口

@AnyThreadpublic static 
boolean invokeAsync( @NonNull String process, Bundle data, @NonNull Class
taskClass, IPCInvokeCallback callback)复制代码
@AnyThreadpublic static 
, InputType extends Parcelable, ResultType extends Parcelable> boolean invokeAsync(String process, InputType data, @NonNull Class
taskClass, IPCRemoteInvokeCallback
callback)复制代码

IPCInvoker使用示例

同步调用

public class IPCInvokeSample_InvokeByType {    private static final String TAG = "IPCInvokerSample.IPCInvokeSample_InvokeByType";    public static void invokeSync() {        Bundle bundle = new Bundle();        bundle.putString("name", "AlbieLiang");        bundle.putInt("pid", android.os.Process.myPid());        IPCString result = IPCInvoker.invokeSync(PushProcessIPCService.PROCESS_NAME,                    bundle, IPCRemoteInvoke_BuildString.class);        Log.i(TAG, "invoke result : %s", result);    }    private static class IPCRemoteInvoke_BuildString implements IPCRemoteSyncInvoke
{ @Override public IPCString invoke(Bundle data) { String msg = String.format("name:%s|fromPid:%s|curPid:%s", data.getString("name"), data.getInt("pid"), android.os.Process.myPid()); Log.i(TAG, "build String : %s", msg); return new IPCString(msg); } }}复制代码

异步调用

public class IPCInvokeSample_InvokeByType {    private static final String TAG = "IPCInvokerSample.IPCInvokeSample_InvokeByType";    public static void invokeAsync() {        Bundle bundle = new Bundle();        bundle.putString("name", "AlbieLiang");        bundle.putInt("pid", android.os.Process.myPid());        IPCInvoker.invokeAsync(PushProcessIPCService.PROCESS_NAME, bundle,                IPCRemoteInvoke_PrintSomething.class, new IPCRemoteInvokeCallback
() { @Override public void onCallback(IPCString data) { Log.i(TAG, "onCallback : %s", data.value); } }); } private static class IPCRemoteInvoke_PrintSomething implements IPCRemoteAsyncInvoke
{ @Override public void invoke(Bundle data, IPCRemoteInvokeCallback
callback) { String result = String.format("name:%s|fromPid:%s|curPid:%s", data.getString("name"), data.getInt("pid"), android.os.Process.myPid()); callback.onCallback(new IPCString(result)); } }}复制代码

上述示例中IPCString是IPCInvoker里面提供的String的Parcelable的包装类,IPCInvoker支持的跨进程调用的数据必须是可序列化的Parcelable(默认支持Bundle)。

当然也可以使用自己实现的Parcelable类作为跨进程调用的数据结构,如:

public class IPCSampleData implements Parcelable {    public String result;    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeString(result);    }    @Override    public int describeContents() {        return 0;    }    public static final Creator
CREATOR = new Creator
() { @Override public IPCSampleData createFromParcel(Parcel in) { IPCSampleData o = new IPCSampleData(); o.result = in.readString(); return o; } @Override public IPCSampleData[] newArray(int size) { return new IPCSampleData[size]; } };}复制代码

跨进程事件监听与分发

IPCInvoker组件中已经对跨进程事件做了封装,只需要写很少的代码就可以实现跨进程事件的监听和分发了.

实现跨进程事件Dispatcher

public class OnClickEventDispatcher extends IPCDispatcher {}复制代码

因为在做跨进程事件分发时使用的是Dispatcher的class name作为key所以dispatcher只需要继承IPCDispatcher即可。

使用IPCObservable注册跨进程事件监听

注册跨进程事件监听

final IPCObserver observer1 = new IPCObserver() {    @Override    public void onCallback(final Bundle data) {        String log = String.format("register observer by Observable, onCallback(%s),                cost : %s", data.getString("result"),                (System.nanoTime() - data.getLong("timestamp")) / 1000000.0d);        Log.i(TAG, log);    }};IPCObservable observable = new IPCObservable("cc.suitalk.ipcinvoker.sample:push", OnClickEventDispatcher.class);// 注册跨进程事件监听observable.registerIPCObserver(observer1)复制代码

反注册跨进程事件监听

// 反注册跨进程事件监听observable.unregisterIPCObserver(observer1)复制代码

发布跨进程事件

发布Bundle事件

OnClickEventDispatcher dispatcher = new OnClickEventDispatcher();Bundle event = new Bundle();event.putString("result", String.format("processName : %s, pid : %s",        IPCInvokeLogic.getCurrentProcessName(), android.os.Process.myPid()));event.putLong("timestamp", System.nanoTime())dispatcher.dispatch(event);复制代码

发布自定义数据结构的跨进程事件

发布自定义数据结构的跨进程事件,该数据结构需要实现IPCData接口(如:IPCSampleData)

实现自定义跨进程事件

public class IPCSampleData implements Parcelable, IPCData {    public String result;    public long timestamp;    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeString(result);        dest.writeLong(timestamp);    }    @Override    public int describeContents() {        return 0;    }    public static final Creator
CREATOR = new Creator
() { @Override public IPCSampleData createFromParcel(Parcel in) { IPCSampleData o = new IPCSampleData(); o.result = in.readString(); o.timestamp = in.readLong(); return o; } @Override public IPCSampleData[] newArray(int size) { return new IPCSampleData[size]; } }; @Override public Bundle toBundle() { Bundle bundle = new Bundle(); bundle.putString("result", result); bundle.putLong("timestamp", timestamp); return bundle; } @Override public void fromBundle(Bundle bundle) { result = bundle.getString("result"); timestamp = bundle.getLong("timestamp"); }}复制代码

注册远端事件监听

final IPCObserver observer1 = new IPCObserver() {    @Override    public void onCallback(final Bundle data) {        IPCSampleData result = new IPCSampleData();        result.fromBundle(data);        String log = String.format("register observer by client, onCallback(%s), cost : %s",                result.result, (System.nanoTime() - result.timestamp) / 1000000.0d);        Log.i(TAG, log);    }};IPCObservable observable = new IPCObservable("cc.suitalk.ipcinvoker.sample:push", OnClickEventDispatcher.class);// 注册跨进程事件监听observable.registerIPCObserver(observer1)复制代码

发布IPCSampleData事件

OnClickEventDispatcher dispatcher = new OnClickEventDispatcher();IPCSampleData event = new IPCSampleData();event.result = String.format("processName : %s, pid : %s", IPCInvokeLogic.getCurrentProcessName(), android.os.Process.myPid());event.timestamp = System.nanoTime();dispatcher.dispatch(event);复制代码

IPCInvoker中的Client?

看到这里想必你已经大致了解IPCInvoker的接口调用了,在使用层面,并没有明显的Client/Server架构的影子,本节中讲到的是IPCInvokerClient。IPCInvokeClient其内部是对IPCInvoker进行了一定的封装,针对指定的远端进程,支持IPCInvoker原本的同步和异步调用,实现了跨进程事件监听逻辑。

IPCInvokeClient的相关接口

@AnyThreadpublic 
boolean invokeAsync(Bundle data, @NonNull Class
taskClass, IPCInvokeCallback callback)复制代码
@AnyThreadpublic 
, InputType extends Parcelable, ResultType extends Parcelable> boolean invokeAsync(InputType data, @NonNull Class
taskClass, IPCRemoteInvokeCallback
callback)复制代码
@WorkerThreadpublic 
Bundle invokeSync(Bundle data, @NonNull Class
taskClass)复制代码
@WorkerThreadpublic 
, InputType extends Parcelable, ResultType extends Parcelable> ResultType invokeSync(InputType data, @NonNull Class
taskClass)复制代码
@AnyThreadpublic boolean registerIPCObserver(String event, @NonNull IPCObserver observer)复制代码
@AnyThreadpublic boolean unregisterIPCObserver(String event, @NonNull IPCObserver observer)复制代码

IPCInvokeClient使用示例

创建IPCInvokeClient

IPCInvokeClient client = new IPCInvokeClient("cc.suitalk.ipcinvoker.sample:push");复制代码

IPCInvokeClient在创建时已经指定远端进程(如示例中指定了远端进程为cc.suitalk.ipcinvoker.sample:push),IPCInvokeClient调 同步/异步 调用接口及跨进程事件监听与分发,均与本文前面介绍的IPCInvoker接口是用是保持一致的,这里不再冗述。

XIPCInvoker

怎么会有个XIPCInvoker?XIPCInvoker与IPCInvokeClient类似,也是对IPCInvoker进行了一定的封装。IPCInvoker中的invokeSync和invokeAsync接口只接受Parcelable或Bundle数据类型,而XIPCInvoker的出现是为了支持更丰富的数据类型(支持普通数据类型).

XIPCInvoker调用接口

异步调用接口

@AnyThreadpublic static 
, InputType, ResultType> void invokeAsync(String process, InputType data, @NonNull Class
taskClass, IPCRemoteInvokeCallback
callback)复制代码

同步调用接口

@WorkerThreadpublic static 
, InputType, ResultType> ResultType invokeSync(String process, InputType data, @NonNull Class
taskClass)复制代码

上述两个接口和IPCInvoker中的同步/异步调用接口不同的地方在于InputTypeResultType不在限定是Parcelable,可以是任意数据类型。

当然需要支持Parcelable之外的数据类型,需要提供该数据类型的BaseTypeTransfer实现类,并在IPCInvoker初始化时将其添加到IPCInvoker的ObjectTypeTransfer中.

支持自定义跨进程数据类型

需实现BaseTypeTransfer接口,并在IPCInvoker初始化时将其添加到ObjectTypeTransfer中。

自定义数据结构TestType

public class TestType {    public String key;    public String value;}复制代码

实现BaseTypeTransfer接口

public class TestTypeTransfer implements BaseTypeTransfer {    @Override    public boolean canTransfer(Object o) {        return o instanceof TestType;    }    @Override    public void writeToParcel(@NonNull Object o, Parcel dest) {        TestType testTypeObj = (TestType) o;        dest.writeString(testTypeObj.key);        dest.writeString(testTypeObj.value);    }    @Override    public Object readFromParcel(Parcel in) {        TestType testTypeObj = new TestType();        testTypeObj.key = in.readString();        testTypeObj.value = in.readString();        return testTypeObj;    }}复制代码

初始化时将TestTypeTransfer添加到ObjectTypeTransfer中

public class IPCInvokerApplication extends Application {    private static final String TAG = "IPCInvokerSample.IPCInvokerApplication";    @Override    public void onCreate() {        super.onCreate();        // Initialize IPCInvoker        IPCInvokerBoot.setup(this, new DefaultInitDelegate() {            @Override            public void onAttachServiceInfo(IPCInvokerInitializer initializer) {                initializer.addIPCService(MainProcessIPCService.PROCESS_NAME, MainProcessIPCService.class);                initializer.addIPCService(PushProcessIPCService.PROCESS_NAME, PushProcessIPCService.class);            }            @Override            public void onAddTypeTransfer(TypeTransferInitializer initializer) {                super.onAddTypeTransfer(initializer);                initializer.addTypeTransfer(new TestTypeTransfer());            }        });    }}复制代码

在XIPCInvoker中使用TestType

TestType data = new TestType();data.key = "wx-developer";data.value = "XIPCInvoker";final IPCInteger result = XIPCInvoker.invokeSync("cc.suitalk.ipcinvoker.sample:push", data, IPCInvokeTask_getInt.class);Log.i(TAG, "result : %s", result.value);复制代码

跨进程事件XIPCDispatcher与XIPCObserver

XIPCDispatcher与XIPCObserver是IPCDispatcher与IPCObserver的扩展,与XIPCInvoker对IPCInvoker相同,XIPCDispatcher与XIPCObserver同样是为了支持自定数据类型而设计的,接口使用与原接口一致,这里就不再冗述了.

相关文章

欢迎使用IPCInvoker,有兴趣的同学可以一起维护该项目。(项目地址为)

转载地址:http://jycwo.baihongyu.com/

你可能感兴趣的文章
循环、迭代、遍历和递归
查看>>
忘记mysql的root密码
查看>>
使用JavaScript 和 CSS 实现图像缩放和剪裁(转)
查看>>
我的友情链接
查看>>
Code Kata 5
查看>>
RHCE_LAB(4)GRUB提升安全性保护root密码安全
查看>>
Zabbix实现微信平台报警----基于zabbix3.0.4
查看>>
android 安全讲座第二层 使用AndBug调试Android Java Bytecode
查看>>
css3 Gradients 线性渐变
查看>>
ucfirst() 函数
查看>>
bootstrap-导航条层次的导航
查看>>
git rm使用
查看>>
xss***代码
查看>>
Python学习网站
查看>>
mybatis基础(一)
查看>>
Python的Django框架中的Context使用
查看>>
我的友情链接
查看>>
linux常用命令
查看>>
Docker在Windows系统下的安装及简单使用介绍
查看>>
CentOS用yum安装X Window
查看>>