使用annotation简化Flutter与Android Native通信的实践

746 阅读3分钟

有一段时间没有做Android的开发了,为了保持对Android的了解也重新看了看Android一些新的知识。发现现在flutter越来越火,以前也听说过flutter但一直没有尝试,最近花了点时间学习了一下flutter和dart。
经过几天学习和了解对flutter也有了一些粗浅的了解。我认为以后如果我在Android开发中使用flutter可能并不会完全从前端界面到后台网络请求都使用dart代码解决,而更可能的是,前端界面使用flutter,后台的网络请求等操作还是用原来Android Native那一套,毕竟在很多公司多年Android开发的积累这一块有着成熟稳定的解决方案。因此我详细的学习了一下flutter与Android Native之间的通信方法和机制。
总的来说,Flutter和Android Native之间的通信还是比较简单的,但是如果后台的操作都依赖Android Native代码,写多了flutter与android native通信处理代码后能发觉这之中还是有很多重复冗余的代码,写多了也很恼人。
于是想到了使用annotation加APT机制,在编译前生成flutter与android native通信设置代码,代码开发时只写业务代码。

flutter与android native通信常规过程:

在dart端调用

//创建channel
static const channel = const MethodChannel("xxxxxxxx/channelName");


void _doLogin() async {
    . . . . . . 

    final result = await channel
        .invokeMethod("doLogin", {"userName":_username, "password":_pwd});
    . . . . . .
}

java端处理

handler代码

上面的java端代码都是在处理flutter与Android Native通信的代码,业务端的逻辑也就是每个case中的一块。并且case中实现还要考虑解析出flutter传入的参数解析,异步调用处理AsyncTask等的创建这些也是可以放到APT自动生成。

使用annotation的方案:

注解handler
上面的Handler就是普通的java代码,通过MethodChannelHandler注解设置,channel的注册信息。用AsyncMethodCall设置dart端调用函数的处理函数与它的结果处理回调函数,并且函数的参数解析自动生成的代码中会实现无需手动解析, 并且这两个函数分别在后台线程和主线程执行,对应于AsyncTaskdoInBackgrouponPostExecute。所有通过注解的handler都只需要在 Activity中执行一条代码完成全部注册:FlutterChannelFactory.register(this);。 使用annotation实现的handler有一些好处:

  • 无需编写flutter channel的模板代码。
  • 无需依赖flutter API和Android API易于本地Junit测试。
  • 当处理方法过多时避免的过多switch...case...代码块,更易读。

实现代码参考:flutter_channel_annotation

总结

简单的实践了一下通过annotation和APT来简化Flutter与Android Native通信。也是在几天对flutter学习的一些思考,可能想法不成熟也可能有更好的办法,还需要对flutter更深入的学习。 另外感觉前端flutter+channel handler+后端android native直接就是MPV模式的实现。flutter作为View,channel handler作为Presenter,其他native代码作为model结构很清晰。