-
Notifications
You must be signed in to change notification settings - Fork 93
3. Remote
gaowei edited this page Nov 15, 2022
·
16 revisions
- 无需写aidl文件
- 支持跨app
- 使用方式几乎等同本地导航Router请求和Service请求,只需增加一些配置即可
- 不需要异步去bindService等待结果,属于同步调用
- 关于反射,服务端执行@Remote注解声明的方法时,无反射
- 支持任意类型的对象跨进程传递,包括自定义类 (建议实现Parcelable,默认使用Gson序列化)
- 服务端进程不存活,也会自动拉起并执行
- 配置服务端manifest,引入一个Provider组件,并指定authority
// 继承RemoteProvider自定义Provider类,一个进程对应一个唯一的Provider类
public class MyProvider extends RemoteProvider {
}
// 客户端Manifest定义(仅跨app调用时需要定义,android11以上系统对ContentProvider的要求)
<manifest>
<queries>
// 值是服务端进程cp的authority
<provider android:authorities="com.server.authority" />
</queries>
<application>
...
<manifest>
// 服务端Manifest定义
<application>
<provider
// 自定义该进程的authority
android:authorities="com.server.authority"
// 使用RemoteProvider子类
android:name="com.my.MyProvider"
// 指定服务端进程名
android:process="..."
// 如果允许其他app访问设置true
android:exported="false" />
</application>
@Router(scheme = "didi", host = "router", path = "/p")
public class SendOrderHandler implements IRouterHandler {
@Override
public void handle(@NonNull Request request, @NonNull Result result);
}
}
- 方法执行默认使用反射的形式执行跨进程方法
- 引入@Remote声明在跨进程的方法上,会自动生成本地代码,替代反射跨进程执行
- @Remote支持任何对象类型,因Javassist的限制仅支持基本类型的包装类
- 仅当跨app时需要注意不要被混淆,同一个app内无需担心混淆
@Service(function = IOrderService.class)
public class OrderService implements IOrderService {
@Remote // 此注解会自动生成本地代码,替代反射
public void handle(String s, Integer i) {
}
}
- 使用方式基本同调用本地组件,仅需要setRemoteAuthority传入自定义的authority即可
// 调用远程RouterHandler
DRouter.build("didi://router/p")
.setRemoteAuthority("com.server.authority")
.start(context);
// 调用远程Service
DRouter.build(IServiceTest.class)
.setRemoteAuthority("com.server.authority")
.getService() //构造方法
.handle("name", 1); //目标方法
- 方法参数可以使用IRemoteCallback作为回调对象,此类支持跨进程callback回来
- 可以像普通的本地监听者模式一样,保存下来,完全忽略跨进程的背景
- 支持泛型
// 服务端Service
@Service(function = IOrderService.class)
public class OrderService implements IOrderService {
private Set<IRemoteCallback> callbacks =
Collections.newSetFromMap(new ConcurrentHashMap<IRemoteCallback, Boolean>());
@Remote
public void register(IRemoteCallback.TypeN<X> callback) {
callbacks.add(callback);
}
@Remote
public void unregister(IRemoteCallback.TypeN<X> callback) {
callbacks.remove(callback);
}
public void callback(...) {
for (IRemoteCallback.TypeN<X> instance : callbacks) {
instance.callback(...);
}
}
- 当服务进程死亡以后,客户端可以等服务端被外力拉起后自动重连,重新执行一遍所有的方法
- 使用生命周期来停止自动重连机制
- 考虑到服务端可能是启动崩溃,所以暂时没有去支持由客户端主动去把死亡的服务端拉起
public class RemoteActivity extends AppCompatActivity {
private IRemoteRegister registerInstance;
private RouterLifecycle lifecycle = new RouterLifecycle();
@Override
protected void onCreate(Bundle savedInstanceState) {
IRemoteRegister registerInstance =
DRouter.build(IRemoteRegister.class)
.setRemoteAuthority("com.server.authority")
.setRemoteDeadResend(Extend.Resend.WAIT_ALIVE)
.setLifecycleOwner(lifecycle)
.getService();
}
@Override
protected void onResume() {
super.onResume();
lifecycle.create();
registerInstance.register(callback);
}
@Override
protected void onStop() {
super.onStop();
lifecycle.destroy();
registerInstance.unregister(callback);
}
private IRemoteCallback callback = new IRemoteCallback() {
@Override
public void callback(Object... data) throws RemoteException {
}
};