鴻蒙開源三方組件 -- 進程間通信的AndLinker組件
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
1.組件
AndLinker是一款OpenHarmony上的IPC (進程間通信) 庫,結(jié)合了[ZIDL][zidl]和[Retrofit][retrofit]的諸多特性,且可以與[RxJava][rxjava]和[RxJava2][rxjava2]的Call Adapters無縫結(jié)合使用。項目的設(shè)計與部分代碼參考了偉大的[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一樣生成遠程服務(wù)接口的IPC實現(xiàn)。
- 支持Call Adapters:Call, RxJava Observable,RxJava2 Observable & Flowable。
- 支持遠程服務(wù)回調(diào)機制。
- 支持AIDL的所有數(shù)據(jù)類型。
- 支持AIDL的所有數(shù)據(jù)定向tag: in,out,inout。
- 支持AIDL的oneway關(guān)鍵字。
4.如何使用
使用注解@RemoteInterface修飾遠程服務(wù)接口IRemoteService,并實現(xiàn)它:
- @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);
- }
在服務(wù)端App中,創(chuàng)建AndLinkerBinder對象,并注冊上面的接口實現(xiàn)。然后在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創(chuàng)建AndLinker對象,并通過create()方法生成一個IRemoteService遠程接口的IPC實現(xiàn):
- 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();
- }
現(xiàn)在mRemoteService對象中的所有方法都是IPC方法。
基本使用-效果展示
AndLinker支持AIDL所有數(shù)據(jù)類型:
- Java語言中的所有原始類型:int,long,char,boolean等等。
- String
- CharSequence
- Paracelable
- List(List中的所有元素必須是此列表中支持的數(shù)據(jù)類型)
- Map(Map中的所有元素必須是此列表中支持的數(shù)據(jù)類型)
- 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");
- }
- });


進階使用-效果展示
1.Call Adapters
在客戶端App中,你可以copy并修改遠程服務(wù)接口,包裝方法的返回值
- @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中注冊對應(yīng)的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();
- }


2.遠程服務(wù)接口回調(diào)
使用@RemoteInterface注解修飾遠程服務(wù)回調(diào)接口IRemoteCallback
- @RemoteInterface
- public interface IRemoteCallback {
- void onStart();
- void onValueChange(int value);
- }
在遠程方法中使用@Callback注解修飾callback參數(shù)
- void registerCallback(@Callback IRemoteCallback callback);
在客戶端App中,實現(xiàn)上面定義的遠程服務(wù)回調(diào)接口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();
- }
- };

3.指定數(shù)據(jù)定向tag
可以為遠程方法的參數(shù)指定@In,@Out或者@Inout注解,標記了數(shù)據(jù)在底層Builder中的流向
- void directionalParamMethod(@In int[] arr, @Out ParcelableObj obj, @Inout Rect rect);
注意:
- 所有非原始類型必須指定數(shù)據(jù)定向tag:@In,@Out,或者@Inout,用來標記數(shù)據(jù)的流向。原始類型默認是@In類型,并且不能指定其他值。
- 使用@Out或者@Inout修飾的Parcelable參數(shù)必須實現(xiàn)SuperParcelable接口,否則你必須手動添加此方法public void readFromParcel(Parcel in)。

4.使用@OnewWay注解
在遠程方法上使用@OneWay注解,這會修改遠程方法調(diào)用的行為。當使用它時,遠程方法調(diào)用不會堵塞,它只是簡單的發(fā)送數(shù)據(jù)并立即返回。
- @OneWay
- void onewayMethod(String msg);

5. 下載鏈接
5.1 IDE下載鏈接
https://developer.harmonyos.com/cn/develop/deveco-studio#download
5.2 源碼鏈接
https://gitee.com/openneusoft/and-linkers
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)