【全网首发】鸿蒙开源三方组件 -- 进程间通信的AndLinker组件 精华
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");
}
});
进阶使用-效果展示
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();
}
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();
}
};
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)。
4.使用@OnewWay注解
在远程方法上使用@OneWay注解,这会修改远程方法调用的行为。当使用它时,远程方法调用不会堵塞,它只是简单的发送数据并立即返回。
@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
做三方组件的都是大佬!
进程间通信的另外一种方式