【全网首发】鸿蒙开源三方组件 -- 进程间通信的AndLinker组件 精华

wx586efde387a4c
发布于 2021-7-27 14:53
浏览
3收藏

1.组件
AndLinker是一款OpenHarmony上的IPC (进程间通信) 库,结合了[ZIDL][zidl]和[Retrofit][retrofit]的诸多特性,且可以与[RxJava][rxjava]和[RxJava2][rxjava2]的Call Adapters无缝结合使用。项目的设计与部分代码参考了伟大的[Retrofit][retrofit]项目。
2.更新Gradle配置
编辑您的build.gradle文件。您必须将以下行添加到该dependencies部分:

dependencies {
   // your app's other dependencies
    implementation 'io.github.dzsf:andlinker:1.0.0'
}

3.功能特性

  • 以普通Java接口代替AIDL接口。
  • 像Retrofit一样生成远程服务接口的IPC实现。
  • 支持Call Adapters:Call, RxJava Observable,RxJava2 Observable & Flowable。
  • 支持远程服务回调机制。
  • 支持AIDL的所有数据类型。
  • 支持AIDL的所有数据定向tag: in,out,inout。
  • 支持AIDL的oneway关键字。

4.如何使用
使用注解@RemoteInterface修饰远程服务接口IRemoteService,并实现它:

@RemoteInterface
public interface IRemoteService {

    int getPid();

    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
                    double aDouble, String aString);

    void registerCallback(@Callback IRemoteCallback callback);

    void directionalParamMethod(@In int[] arr, @Out ParcelableObj obj, @Inout Rect rect);

    @OneWay
    void onewayMethod(String msg);
}

在服务端App中,创建AndLinkerBinder对象,并注册上面的接口实现。然后在onBind()方法中返回,暴露给客户端:

    private AndLinkerBinder mLinkerBinder;
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        HiLog.debug(label, "Service onCreate()");
        mLinkerBinder = AndLinkerBinder.Factory.newBinder();
        mLinkerBinder.registerObject(mRemoteService);
        mLinkerBinder.registerObject(mRemoteTask);
    }

    @Override
    public IRemoteObject onConnect(Intent intent) {
        HiLog.debug(label, "Service onBind()");
        return (IRemoteObject) mLinkerBinder;
    }

在客户端App中,通过Builder创建AndLinker对象,并通过create()方法生成一个IRemoteService远程接口的IPC实现:

public class MainAbilitySlice extends AbilitySlice implements AndLinker.BindCallback,Component.ClickedListener{
    private static final String TAG = "BindingActivity";
    private static final String REMOTE_SERVICE_PKG = "com.example.andlinker";
    public static final String REMOTE_SERVICE_ACTION = "com.example.andlinker.REMOTE_SERVICE_ACTION";
    private HiLogLabel label = new HiLogLabel(HiLog.ERROR,0,TAG);
    private IRemoteTask mRemoteTask;
    private IRemoteService mRemoteService;
    private AndLinker mLinker;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        mLinker = new AndLinker.Builder(this)
                .packageName(REMOTE_SERVICE_PKG)
                .action(REMOTE_SERVICE_ACTION)
                .className("com.example.andlinker.RemoteService")
                .addCallAdapterFactory(OriginalCallAdapterFactory.create()) // Basic
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())  // RxJava2
                .build();
        mLinker.setBindCallback(this);
        mLinker.registerObject(mRemoteCallback);
        mLinker.bind();
}

现在mRemoteService对象中的所有方法都是IPC方法。
基本使用-效果展示
AndLinker支持AIDL所有数据类型:

  • Java语言中的所有原始类型:int,long,char,boolean等等。
  • String
  • CharSequence
  • Paracelable
  • List(List中的所有元素必须是此列表中支持的数据类型)
  • Map(Map中的所有元素必须是此列表中支持的数据类型)
 Button buttonBtnPid = (Button) findComponentById(ResourceTable.Id_btn_pid);
        buttonBtnPid.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                ToastDialog dialog = new ToastDialog(MainAbilitySlice.this);
                dialog.setText("Server pid: " + mRemoteService.getPid()).show();
            }
        });

 Button buttonBtnBasicTypes = (Button) findComponentById(ResourceTable.Id_btn_basic_types);
        buttonBtnBasicTypes.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                mRemoteService.basicTypes(1, 2L, true, 3.0f, 4.0d, "str");
            }
        });

【全网首发】鸿蒙开源三方组件 -- 进程间通信的AndLinker组件-鸿蒙开发者社区
【全网首发】鸿蒙开源三方组件 -- 进程间通信的AndLinker组件-鸿蒙开发者社区
进阶使用-效果展示
1.Call Adapters
在客户端App中,你可以copy并修改远程服务接口,包装方法的返回值

@RemoteInterface
public interface IRemoteService {

    int getPid();

    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
                    double aDouble, String aString);

    void registerCallback(@Callback IRemoteCallback callback);

    void directionalParamMethod(@In int[] arr, @Out ParcelableObj obj, @Inout Rect rect);

    @OneWay
    void onewayMethod(String msg);
}

在AndLinker.Builder中注册对应的Call Adapter Factory

public class MainAbilitySlice extends AbilitySlice implements AndLinker.BindCallback,Component.ClickedListener{
    private static final String TAG = "BindingActivity";
    private static final String REMOTE_SERVICE_PKG = "com.example.andlinker";
    public static final String REMOTE_SERVICE_ACTION = "com.example.andlinker.REMOTE_SERVICE_ACTION";
    private HiLogLabel label = new HiLogLabel(HiLog.ERROR,0,TAG);
    private IRemoteTask mRemoteTask;
    private IRemoteService mRemoteService;
    private AndLinker mLinker;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        mLinker = new AndLinker.Builder(this)
                .packageName(REMOTE_SERVICE_PKG)
                .action(REMOTE_SERVICE_ACTION)
                .className("com.example.andlinker.RemoteService")
                .addCallAdapterFactory(OriginalCallAdapterFactory.create()) // Basic
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())  // RxJava2
                .build();
        mLinker.setBindCallback(this);
        mLinker.registerObject(mRemoteCallback);
        mLinker.bind();
}

【全网首发】鸿蒙开源三方组件 -- 进程间通信的AndLinker组件-鸿蒙开发者社区
【全网首发】鸿蒙开源三方组件 -- 进程间通信的AndLinker组件-鸿蒙开发者社区
2.远程服务接口回调
使用@RemoteInterface注解修饰远程服务回调接口IRemoteCallback

@RemoteInterface
public interface IRemoteCallback {

    void onStart();

    void onValueChange(int value);
}

在远程方法中使用@Callback注解修饰callback参数

void registerCallback(@Callback IRemoteCallback callback);

在客户端App中,实现上面定义的远程服务回调接口IRemoteCallback,并且注册到AndLinker中

private final IRemoteCallback mRemoteCallback = new IRemoteCallback() {

        @Override
        public void onStart() {
            HiLog.debug(label,"Server callback onStart!");
        }

        @Override
        public void onValueChange(int value) {
            // Invoke when server side callback
            ToastDialog dialog = new ToastDialog(MainAbilitySlice.this);
            dialog.setSize(1000,200);
            dialog.setText( "Server callback value: " + value).show();
        }
    };

【全网首发】鸿蒙开源三方组件 -- 进程间通信的AndLinker组件-鸿蒙开发者社区
3.指定数据定向tag
可以为远程方法的参数指定@In,@Out或者@Inout注解,标记了数据在底层Builder中的流向

void directionalParamMethod(@In int[] arr, @Out ParcelableObj obj, @Inout Rect rect);

注意:

  • 所有非原始类型必须指定数据定向tag:@In,@Out,或者@Inout,用来标记数据的流向。原始类型默认是@In类型,并且不能指定其他值。
  • 使用@Out或者@Inout修饰的Parcelable参数必须实现SuperParcelable接口,否则你必须手动添加此方法public void readFromParcel(Parcel in)。

【全网首发】鸿蒙开源三方组件 -- 进程间通信的AndLinker组件-鸿蒙开发者社区
4.使用@OnewWay注解
在远程方法上使用@OneWay注解,这会修改远程方法调用的行为。当使用它时,远程方法调用不会堵塞,它只是简单的发送数据并立即返回。

@OneWay
void onewayMethod(String msg);

【全网首发】鸿蒙开源三方组件 -- 进程间通信的AndLinker组件-鸿蒙开发者社区
5. 下载链接
5.1 IDE下载链接
https://developer.harmonyos.com/cn/develop/deveco-studio#download
5.2 源码链接
https://gitee.com/openneusoft/and-linkers

已于2021-7-27 14:53:14修改
2
收藏 3
回复
举报
2条回复
按时间正序
/
按时间倒序
Anzia
Anzia

做三方组件的都是大佬!

回复
2021-7-28 21:37:13
wx610273f694f1c
wx610273f694f1c

进程间通信的另外一种方式

回复
2021-7-29 17:56:52
回复
    相关推荐