本文转载请联系唯一大学前端技术公众号。前言Flutter2主要带来Null安全趋于稳定等新特性,桌面和Web支持也正式宣布进入稳定通道。最受关注的是Add-to-App相关的更新,以改善Flutter2之前版本组合不好的开发体验。所谓的Add-to-App只是将Flutter添加到现有的iOS和Android应用程序中以利用Flutter,这是一种在两个移动平台上重用Flutter代码同时仍保留现有原生代码库的好方法。在这个方案出现之前,类似的第三方支持包括flutter_boost、flutter_thrio等,但是这些方案必须面对的问题是:非官方的支持必然存在每个版本都需要适配的问题,并且根据当前的更新Flutter的速度,很可能每个季度都会有版本的大变动,所以如果开发者不及时维护或维护,那么这种侵入性强的框架很容易成为项目的瓶颈。Flutter2多引擎混合开发基本使用1.首先创建一个Android原生项目,(Android原生项目创建过程略过)2.Android项目创建引入FlutterModule,使用File->New->NewModule...->选择FlutterModule,然后指定一个模块名称,填写相关信息,最后点击确定等待Gradle同步完成。3.Android项目集成FlutterModule1)创建一个FlutterEngineGroup对象。FlutterEngineGroup可以用来管理多个FlutterEngine对象。资源可以在多个FlutterEngine之间共享。这样多个FlutterEngine占用的资源会相对少一些。FlutterEngineGroup需要在Application创建的onCreate方法中创建。packagecom.zalex.hybird;importandroid.app.Application;importio.flutter.embedding.engine.FlutterEngineGroup;publicclassWYApplicationextendsApplication{publicFlutterEngineGroupengineGroup;@OverridepublicvoidonCreate(){super.onCreate();//创建一个FlutterEngineGroup对象engineGroup=newGroup(this)Engine}2)创建WYFlutterEngineManager缓存管理类。通过FlutterEngineCache缓存类,首先从中获取缓存的FlutterEngine。如果没有,则通过findAppBundlePath和entrypoint创建一个DartEntrypoint对象。这里的findAppBundlePath主要是默认的flutter_assets目录;而entrypoint其实就是dart代码中启动方法的名称;它还绑定了dart中runApp的方法,然后通过createAndRunEngine方法创建了一个FlutterEngine,然后缓存起来。publicclassWYFlutterEngineManager{publicstaticFlutterEngineflutterEngine(Contextcontext,StringengineId,StringentryPoint){//1.从缓存中获取FlutterEngineFlutterEngineengine=FlutterEngineCache.getInstance().get(engineId);if(engine==null){//如果缓存中没有FlutterEngine//1.新建一个FlutterEngine,执行的入口函数是entryPointWYApplicationapp=(WYApplication)context.getApplicationContext();DartExecutor.DartEntrypointdartEntrypoint=newDartExecutor.DartEntrypoint(FlutterInjector.instance().flutterLoader().findAppBundlePath(),entryPoint);engine=app.engineGroup.createAndRunEngine(context,dartEntrypoint);//2.存入存入存入flutterEnginecache.getInstance()。onCreate(savedInstanceState);flutterBindings=newWYFlutterBindings(这个,SingleFlutterActivity.class.getSimpleName(),“主要”,这个);flutterBindings.attach();}@OverrideprotectedvoidonDestroy(){super.onDestroy();flutterBindings.detach();}@OverridepublicFlutterEngineprovideFlutterEngine(@NonNull@NotNullContextcontext){returnflutterBindings.getEngine();}@OverridepublicvoidonNext(){IntentflutterIntent=newIntent(this,MainActivity.class);startActivity(flutterIntent);}}Fragment绑定flutter引引擎入口intengineId=engineId;//自定义引引擎IdintfragmentId=1233444;//自定义FragmentIdFrameLayoutflutterContainer=newFrameLayout(this);root.addView(flutterContainer);flutterContainer.setId(containerId);flutterContainer.setLayoutParams(newLinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,FrameLayout.LayoutParams.MATCH_PARENT,1.0f));WYFlutterBindingsflutterBindings=newWYFlutterBindings(this,"WYTopFragment","fragmentMain",this);FlutterEngineengine=bottomBindings.getEngine();FlutterEngineCache.getInstance().put(engineId+"",engine);FragmentflutterFragment=FlutterFragment.withCachedEngine(engineId+"").build();fragmentManager.beginTransaction().add(containerId,flutterFragment).commit();3)flutter模块引擎入口绑定,在除主入口外,其他引擎入口需要添加@pragma('vm:entry-point')注解voidmain()=>runApp(MyApp(Colors.blue));@pragma('vm:entry-point')voidfragmentMain()=>runApp(CustomApp(Colors.green));Flutter2多引擎混合开发与单引擎混合开发对比1.Flutter多引擎方案一直由flutterapi支持。可以创建多个引擎,渲染很多不同的界面也是独立的,但是每启动一个flutterengine,都会占用一个独立的engine。通过测试可以发现一个引擎是40M,创建10个引擎消耗235M,占用内存很大。这在开发过程中是不可接受的。2、由于Flutter2之前版本的多引擎缺陷,业界的做法是复用isolate或者engine来解决。影响最大的是以FlutterBoost、Thrio为代表的单引擎浏览器方案。即使用Activity/ViewController作为承载Dart页面的浏览器,在页面切换时detach/attach单个engine,将页面切换通知Dart层,实现Engine的复用。由于只持有一个Engine单例,只创建一个isolate,Dart层共享通信和资源,可以显着减少内存丢失。但是单引擎实现依赖于修改官方的io.flutter包,对flutter框架做比较大的结构修改。3、从Flutter2开始,使用FlutterEngineGroup在多个引擎下创建一个新的Engine。官方称内存丢失仅占180K。本质是Engine可以共享GPUcontext、glyphs和isolategroupsnapshot,从而实现更快的初始速度和更低的内存占用。4、Flutter2和Flutter1引擎创建的区别:Flutter1引擎创建//Androidvalengine=FlutterEngine(this)engine.dartExecutor.executeDartEntrypoin(DartExecutor.DartEntrypoint.createDefault())FlutterEngineCache.getInstance().put(1,engine)valintent=FlutterActivity.withCacheEngine(1).build(this)//iOSletengine=FlutterEngine()engine.run()letvc=FlutterViewController(engine:engine,nibName:nil,bundle:nil)Fluter2引擎构建//AndroidvalengineGroup=FlutterEngineGroup(context)valengine1=engineGroup.createAndRunDefaultEngine(context)valengine2=engineGroup.createAndRunEngine(context,DartExecutor.DartEntrypoint(FlutterInjector.instance().flutterLoader().findAppBundlePath(),"anotherEntrypoint"))//iOSletengineGroup=FlutterEngineGroup(名称:"example",project:nil)letengine1=engineGroup.makeEngine(withEntrypoint:nil,libraryURI:nil)letengine2=engineGroup.makeEngine(withEntrypoint:"anotherEntrypoint",libraryURI:nil)5.Flutter混合开发方案对比6.Flutter更轻量引擎与单引擎优缺点对比后记本文使用代码和表格本节我们介绍了使用Flutter2多引擎、多引擎混合开发和单引擎混合开发的区别,以及优缺点对比。下一节我们将学习Flutter2多引擎实现的原理。
