FIDL:Flutter与原生通讯的新姿势,不局限于基础数据类型

void initUser(User user);

}

2、执行命令./gradlew assembleDebug,生成IUserServiceStub类和fidl.json文件

3、打开通道,向Flutter公开方法

FidlChannel.openChannel(getFlutterEngine().getDartExecutor(), new IUserServiceStub() {

@Override

void initUser(User user){

System.out.println(user.name + " is " + user.age + "years old!");

}

}

Flutter侧

1、拷贝fidl.json文件到fidl目录,执行命令flutter packages pub run fidl_model,生成Dart接口类

2、绑定Android侧的IUserServiceStub通道

await Fidl.bindChannel(IUserService.CHANNEL_NAME, _channelConnection);

3、调用公开方法

await IUserService.initUser(User());

编译,运行,你将能在Logcat中看到_Oscar is 18 years old!_。

FIDL使用详解

这一部分是对少啰嗦,先看东西部分的补充解释,观众姥爷们可以自行跳过。

上面的例子中的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文件,如下:

这些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类:

即:

  • 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<byte[]> encode(Object... objects);

T decode(byte[] input, TypeLiteral type);

}

Dart:

abstract class ObjectCodec {

dynamic decode(Uint8List input);

List encode(List objects);

}

目前使用的是JsonObjectCodec,经过JSON的编解码,性能会稍差。后面还希望和小伙伴们一起努力,实现更高效的编解码。

项目进度

上述提到的功能,只要是从Flutter侧调用Java侧的方法相关的,大部分都已经实现了。

我做了一个Demo,模拟了一个在Android侧依赖了IM(即时通讯)SDK,需要在Flutter侧聊天、获取消息、发消息的场景。以下是Demo的截图:

1、首页,点击按钮调用Android侧方法,开启聊天服务

2、聊天页面

3、发一条消息给Lucy并获取和Lucy的聊天记录

4、调用Android侧方法发送N条消息给Wilson并获取聊天记录

最后

[外链图片转存中...(img-grJ8YOfT-1738303721419)]

2、聊天页面

[外链图片转存中...(img-N6uHwvJk-1738303721420)]

3、发一条消息给Lucy并获取和Lucy的聊天记录

[外链图片转存中...(img-wIseQO2A-1738303721420)]

4、调用Android侧方法发送N条消息给Wilson并获取聊天记录

[外链图片转存中...(img-a2Hu3Pke-1738303721421)]

最后

相关推荐
小龙在山东11 小时前
Flutter开发环境配置
flutter
字节全栈_ZKt14 小时前
微店的Flutter混合开发组件化与工程化架构
flutter·架构·蓝桥杯
恋猫de小郭2 天前
Flutter 新春第一弹,Dart 宏功能推进暂停,后续专注定制数据处理支持
android·java·flutter
LuiChun2 天前
webview_flutter_wkwebview3.17.0 --Cookie认证
flutter
smart_ljh3 天前
国内flutter环境部署(记录篇)
flutter
LuiChun3 天前
Flutter中使用WebView加载html页面时下载js_css文件的流程
flutter
CherishTaoTao3 天前
Flutter子页面向父组件传递数据方法
开发语言·javascript·flutter
黄油奥特曼5 天前
Flutter解决macbook M芯片Android Studio中不显示IOS真机的问题
flutter·ios·android studio·m芯片
LuiChun5 天前
webview_flutter 4.10.0 技术文档
flutter