本人主要从事android开发,从开始研究到项目实战接入大概有一个半月了,前期的摸索阶段花的时间不是很多,每天抽出1小时来看,学习路线大概是:
搭建环境---语言熟悉---写demo---写案例----摘取实际项目中的模块完全翻译为dart版本----接入到项目中
目前还算顺利,遇到的问题大都解决了。dart语法类似于js,也和java8,kt等以后的语法糖相通,熟悉下即可上手。
我随手记录了些比较繁琐难解决,实施不是很简单的问题,类似于widget布局等就不再详细描述了,只是时间问题,熟悉下就行了。
我们项目中嵌入Flutter的入口是主页的第四个tab,需要一个fragment,可以在flutterfragment中return flutterView。
public class MyFlutterFragment extends BaseFlutterFragment implements BasicMessageChannel.MessageHandler<String>{
private BasicMessageChannel<String> messageChannel;
@Override
public FlutterView onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FlutterView flutterView = Flutter.createView(
mActivity,
getLifecycle(),
"routename");
messageChannel = new BasicMessageChannel<>(flutterView, "android_channel", StringCodec.INSTANCE);
messageChannel.setMessageHandler(this);
//todo 注册你的methodChannel
// ......
return flutterView;
}
@Override
public void onMessage(String s, BasicMessageChannel.Reply<String> reply) {
//todo
}
}
向你的flutter的main()方法中传递routename 然后启动相应的widget,本身没有什么问题,嵌入之后widget渲染和请求也ok,只是在切换flutterFragment和nativeFragment的时候出现了明显的闪烁,而nativeFragment之间切换则没有。
翻阅源码可以看到flutterView本身就是surfaceView,做android原生开发朋友知道,即使不使用flutter,在做自定义相机,视频渲染,以及类似于XWalkView 的使用中都会遇到类似问题。
对flutter了解不深,不明白为何选取surface来做载体,使用textureView会有什么问题。
【Surfaceview的特性】:内部维护了两个线程即主线程和渲染线程,渲染线程可以在主线程之外的线程中向屏幕上绘图。这样可以避免主线程因绘图任务繁重导致程序的阻塞,从而提高了程序的反应速度。在游戏开发中多用surfaceView,游戏的背景,任务,动作尽量在画布Canvas中绘制。这种双线程的设计模式,极大的消耗了CPU内存,为此,SurfaceView可见时才被创建,SurfaceView隐藏时便被销毁,从而达到节约内存的目的。
搜索资料,由于场景不同解决方案也不同。
1 假如单页面中嵌套surfaceView,可以在Activity的onCreate()方法中加上一句话:
getWindow().setFormat(PixelFormat.TRANSLUCENT);
或在rootview中构建一个长宽为0px 并且不可见的SurfaceView。
2 有人遇到了xwalkView中的闪烁,https://blog.csdn.net/qq2364121253/article/details/82253996,解决方案在文章内。
3 有人在flutter的GitHub issue中提了问题,主要是在原生中启动flutter页面(而非act中嵌入Fragment)的闪烁和黑屏问题,和重置flutterView大小遇到的问题
https://github.com/flutter/flutter/issues/19189
综合几种方案,可以找到一个比较简单的方式, 构建你的flutterView后设置属性
public class MyFlutterFragment extends BaseFlutterFragment implements BasicMessageChannel.MessageHandler<String>{
private BasicMessageChannel<String> messageChannel;
@Override
public FlutterView onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FlutterView flutterView = Flutter.createView(
mActivity,
getLifecycle(),
"routename");
//添加
flutterView.setZOrderOnTop(true);
flutterView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
messageChannel = new BasicMessageChannel<>(flutterView, "android_channel", StringCodec.INSTANCE);
messageChannel.setMessageHandler(this);
//todo 注册你的methodChannel
// ......
return flutterView;
}
@Override
public void onMessage(String s, BasicMessageChannel.Reply<String> reply) {
//todo
}
}
后续我会继续做记录,标记一些问题,最近在弄混合栈,在原生-flutter - web中自由跳转,借鉴咸鱼的混合栈(因为有些bug和不必要功能,暂时没有采用)的思路,大家都可以写出自己的路由栈。