上面的例子中的Map,一般来说,在Java中会对应一个类:
public class User {
String name;
int age;
String country;
Gender gender;
}
enum Gender {
MALE, FEMALE
}
如果想让flutter传输这个对象而不用在flutter层手动去编写User这个类,以及编写fromJson/toJson方法,你可以这样做:
Android侧
1、定义一个接口,添加注解@FIDL。这个注解将告知annotationProcessor生成一些接口和类的描述文件。
@FIDL
public interface IUserService {
void initUser(User user);
}
接口方法的限制如下:
- 由于dart不支持方法重载,所以接口中不能出现同名方法
- 参数只支持实体类,不支持回调
- 由于JSON解码的限制,Java需要有无参构造函数
2、Android Studio点击sync,或者执行:
./gradlew assembleDebug
然后就会产生一堆json文件,如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oCVMvuSt-1647447065078)(https://user-gold-cdn.xitu.io/2020/3/16/170e226e1aeed837?imageView2/0/w/1280/h/960/ignore-error/1)]
这些json文件就是FIDL和类的描述文件。没错,也会同时生成User引用的Gender类的描述文件。
同时,还会生成IUserService的实现IUserServiceStub。即:
- com.infiniteloop.fidl_example.IUserService.fidl.json
- com.infiniteloop.fidl_example.User.json
- com.infiniteloop.fidl_example.Gender.json
- com.infiniteloop.fidl_example.IUserServiceStub.java
限制:只能生成有强引用关系的FIDL文件,被FIDL接口强引用的类的子类如果没有被FIDL接口强引用,则不会生成相应的描述文件。
3、在合适的地方打开通道,向Flutter公开方法
IUserServiceStub userService = new IUserServiceStub() {
@Override
void initUser(User user){
System.out.println(user.name + ” is ” + user.age + “years old!”);
}
FidlChannel.openChannel(getFlutterEngine().getDartExecutor(), userService);
4、如有需要,可以在合适的地方关闭通道
FidlChannel.closeChannel(userService);
关闭的消息将通知到Flutter侧。
Flutter侧
1、进入到你的flutter项目,在lib目录下创建fidl目录,把上面的json文件拷贝到这个目录,然后执行:
flutter packages pub run fidl_model
然后就能在fidl目录下自动生成相关的dart类:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CWU9QZpy-1647447065080)(https://user-gold-cdn.xitu.io/2020/3/16/170e2273c94ff59f?imageView2/0/w/1280/h/960/ignore-error/1)]
即:
- User.dart
- Gender.dart
- IUserService.dart
2、绑定Android侧的IUserServiceStub通道
bool connected = await Fidl.bindChannel(IUserService.CHANNEL_NAME, _channelConnection);
_channelConnection用于跟踪IUserService通道的连接状态,通道连接成功时,会回调它的onConnected方法;通道连接断开时,会回调它的onDisconnected方法。
3、调用通道的公开方法
if (_channelConnection.connected) {
await IUserService.initUser(User());
}
4、如果不再需要使用这个通道了,可以解除绑定
await Fidl.unbindChannel(IUserService.CHANNEL_NAME, _channelConnection);
当然,FIDL的功能不止于此
1、多个参数的FIDL接口
void init(String name, Integer age, Gender gender, Conversation conversation);
2、带返回值的FIDL接口
UserInfo getUserInfo();
3、支持泛型类的生成
public class User {
T country;
}
public class AUser{}
FIDL接口:
void initUser(AUser user);
将能在dart侧生成AUser和User类,且能保持继承关系。
4、传递枚举
void initEnum0(EmptyEnum e);
String initEnum1(MessageStatus status);
5、传递集合、Map
void initList0(List ids);
void initList1(Collection ids);
void initList7(Stack ids);
void initList10(BlockingQueue ids);
6、传递复杂对象。继承、抽象、泛型、枚举和混合类,来一个打一个。
当然,FIDL能做的不止于此
现在,FIDL项目只实现了从Dart侧调用Android侧的方法。还有以下工作要做:
- Android侧调用Dart侧的方法
- 其它平台和Flutter方法的互相调用
- EventChannel,EventChannel本质上是可以通过MethodChannel实现的,问题不大
搞定了对象传输,这些问题,都是小case啦。
对于对象的序列化和反序列化
为了能满足大佬们的定制化需求,我分别在Java侧和Flutter侧定义了序列化/反序列化的接口类。
Java:
public interface ObjectCodec {
List encode(Object… objects);
T decode(byte[] input, TypeLiteral type);
}
Dart:
最后
**要想成为高级安卓工程师,必须掌握许多基础的知识。**在工作中,这些原理可以极大的帮助我们理解技术,在面试中,更是可以帮助我们应对大厂面试官的刁难。
【Android核心高级技术PDF文档,BAT大厂面试真题解析】点击:Android架构视频+BAT面试专题PDF+学习笔记即可获取!
/github.com/a120464/Android-P7/blob/master/Android%E5%BC%80%E5%8F%91%E4%B8%8D%E4%BC%9A%E8%BF%99%E4%BA%9B%EF%BC%9F%E5%A6%82%E4%BD%95%E9%9D%A2%E8%AF%95%E6%8B%BF%E9%AB%98%E8%96%AA%EF%BC%81.md)即可获取!**