Flutter插件初始化方法registerWith及onAttachedToEngine方法细谈

8,651 阅读3分钟

问题初现

最近在个人插件Pangolin的使用反馈中,有很多同学给我反映了一个问题🧐问题截图

年轻的看法🤥

这个问题第其实反应的人并不多,所以一开始没有太在意,稍稍分析了一下原因,很明显啊,context is null📌,这还不简单?“context 没获取到”、“不要在main函数调用”、“增加延时启动策略”,这是我对第一批发现问题的童鞋们的答复,在这里如果有第一批的童鞋能看到的话,我先道个歉🍡,才疏学浅,给大家添麻烦了。但是,但是!真的有人放到页面方法里之后解决了这个问题...,所以,我也不是纯粹的误导👀,哈哈哈哈哈哈。

正文开始

疑惑

后来有一位细心的同学说他打了断点,显示context已经初始化了,而插件内却没有获取到。还有这种操作?哦豁🤔,怎么肥四,我沿着代码一路找,终于,发现了一个不对劲的地方。 这是插件中获取context最开始的地方,梦开始的地方💡。检查了以后,我竟然发现,部分同学竟然在插件初始化的时候不走这个onAttachedToEngine()方法。当时我就惊了😟,现在都这么🐮🍺了吗,engine都不attach了。你这flutter有问题吧,但是flutter doctor 检查一切正常啊!✅。再之后我就发现了另一个可疑函数! 这是个什么角色?!🎭,碰瓷儿的?不试不知道,一试吓一跳,部分同学没走onAttachedToEngine(),却走了registerWith()。这是咋回事儿呢?

眉目

终于在Flutter的1.12迁移记录里,我找到了眉目😇 说了一大堆,啥意思呢?🤓大致意思就是,大致意思就是官方已经提供了新的Android Plugin API,但是对于老的Plugin API不会立即弃用,建议大家赶紧迁移一下自己的插件。新的API中插件都以*Plugin.java的命名方式存在。新的插件要继承FlutterPluginMethodCallHandler(官方还提到如果要使用Activity则需要继承ActivtiyAware)。在以前你的插件继承了MethodCallHandler之后,就会提供registerWith()方法,在registerWith()中初始化MethodCallHandler。但是新版已经使用onAttachedToEngine()方法初始化MethodCallHandler,在我们编写新版插件的过程中依然能够看到registerWith()方法,是官方为了兼容支持旧版本插件⛏。这我就明白了嘛!我全都写在onAttachedToEngine()方法里,确实有一部分同学是不会走的。因为老版本压根没有这个方法😕。

搞定

究竟如何去处理这个新老API的交接会更优雅,更严谨呢?我在GitHub看了很多官方插件的写法,找到PackageInfo的写法,最为稳妥,这里也提供给大家作为参考。 新版本的同学没有任何问题,按照onAttachedToEngine()放心大胆的往前冲,对于旧版的同学,没关系~,我贴心的拓展了一个onAttachedToEngine(),在registerWith()里面调用,并且在这个自定义的onAttachedToEngine()里初始化、绑定界面,这样,你的老插件就是新插件了,焕然一新🤩。目前为止,已经没有人给我反应context is null的问题了~

收获

其实在这次问题排查中,自己还是太自负,太不认真了,面对问题抱着想当然的态度,没有仔细探究问题,这是程序员的大忌🤐。之后自己的问题排查,代码编写中应该始终提醒自己注意严谨性,各种可能性。当然结果来说学习到了知识,对我来说是有收获的,之后在编程中也会更注意这个点。