Flutter填坑系列之Amap(1)
简介
随着Flutter的推出,使得移动端Write once, Run anywhere 变得可能,但是由于前期Flutter库数量以及质量都不够丰富,所以必然会导致Native层代码的编写。
此次就给介绍下Flutter中地图模块的使用情况,以及所遇到的各种坑......
一、配置安装
参考https://github.com/yohom/amap_base_flutter
需要注意的是:
1、默认Plugin中支持的是AndroidX,这就要求了如果之前还没有兼容AndroidX的项目,首先需要处理AndroidX兼容问题。
2、Android运行注意事项:指定项目的编译选项Additional arguments增加--target-platform android-arm (如果机器是64位,记得添加64,如果不添加,部分机型奔溃)从
Flutter填坑系列之Amap(1)
简介
随着Flutter的推出,使得移动端Write once, Run anywhere 变得可能,但是由于前期Flutter库数量以及质量都不够丰富,所以必然会导致Native层代码的编写。
此次就给介绍下Flutter中地图模块的使用情况,以及所遇到的各种坑......
一、配置安装
参考https://github.com/yohom/amap_base_flutter
需要注意的是:
1、默认Plugin中支持的是AndroidX,这就要求了如果之前还没有兼容AndroidX的项目,首先需要处理AndroidX兼容问题。
2、Android运行注意事项:指定项目的编译选项Additional arguments增加--target-platform android-arm (如果机器是64位,记得添加64,如果不添加,部分机型奔溃)
IOS目前还只是preview状态, 默认是不支持的, 需要手动打开开关, 在info.plist文件中新增一行io.flutter.embedded_views_preview为true
3、Android打包注意事项:
增加了Android so文件的Flutter项目需要 在指令flutter build apk 后增加 --target-platform android-arm,同理,64位机记得改为arm64。
二、Amap库中的一些坑
1、生命周期管理
在Flutter中,如果一个组件生命周期接近尾声,通常会通过dispose在处理身后事,然而在之前的开发中,我发现Amap中的dispose并不怎么好使,页面销毁后再次调用Amap的一些方法时,在IOS端直接原地爆炸,并且没有任何异常报错...... 跟踪代码才发现dispose如下:
void dispose() {}
这就明白奔溃的原因了...... AmapController因为引用的存在并没有及时被销毁,但是AmapView是NativeView,以及被销毁了(后续章节会讲述NativeView的一些知识),上层Flutter通过MethodChannel通信机制同步信息到AmapView的时候,因为AmapView已经被销毁,所以直接Native层直接崩溃。
解决方案:
最好的解决方案当然是自己注意控件的生命周期,不要乱用,但是谁要保不准会出现什么奇葩现象,所以,我就在Flutter层增加了关于AmapView等生命周期判断,这样不管怎么乱来,起码不会崩溃了...... 代码如下:
AMapController.withId(int id)
: _mapChannel = MethodChannel('me.yohom/map$id'),
_markerClickedEventChannel = EventChannel('me.yohom/marker_clicked$id'),
_isActive = true;
void dispose() {_isActive = false;}
void deActive(){
_isActive = false;
}
void active(){
_isActive = true;
}
bool isActive(){
return _isActive;
}
2、点击Marker崩溃问题(IOS)
这个是我遇到过最心塞的问题了:崩就崩吧,和上个问题一样,没有任何报错......直接虚拟断开连接。
解决方案:如果需要地图增加Marker点,那么请先增加一个Marker点的点击回调监听......具体原因会在后续章节,做Amap源码分析的时候进行讲解。
3、addMarks镜头移动问题(IOS)
先看下Flutter的调用:
Future addMarkers(
List optionsList, {
bool moveToCenter = true,
bool clear = true,
}) {
final _optionsListJson =
jsonEncode(optionsList.map((it) => it.toJson()).toList());
L.p('方法addMarkers dart端参数: _optionsListJson -> $_optionsListJson');
return _mapChannel.invokeMethod(
'marker#addMarkers',
{
'moveToCenter': moveToCenter,
'markerOptionsList': _optionsListJson,
'clear': clear,
},
);
}
理论上来说,addMarks提供了是否进行移动的设置,然鹅,在IOS平台并没有什么卵用......这就很尴尬了,我的项目里涉及到了大量marker点的使用(参考自如那种),如果每次marker点的批量增加都会涉及到镜头的移动,那不尴尬死??? 这里有个粗暴的解决方案,就是直接进入IOS代码进行修改.......
进到IOS的工程里,找到对应文件
当然暴力删除法并不优雅,后续章节会介绍MethodChannel的使用已经如何处理这个问题......
4、Android打包真机运行崩溃
就像我之前所的那样,不要仅仅只用flutter build apk打包,记得告诉编译器你要打包的native类型:lutter build apk --target-platform android-arm(记得如果是64位,增加下64)
5、And More
最大的问题其实是,Flutter_Amap并不能给基于地图开发功能足够的地图功能支持,例如:地图移动事件回调,地图点击事件反馈,点聚合...... 这些问题,下篇见
总的来说,Flutter现在在移动端会有三方库支持不足的问题(要么根本没有、有么就是残缺版)......毕竟flutter还年轻,随着时间的推移,这些问题也将不再是问题。