在实践的作业场景中,咱们很难从零开始用纯Flutter去建设一个项目,也正是由于这样,Native+Flutter混合栈跳转处理使咱们在混合开发的时分不得不首要考虑的问题,由于咱们很难保证不会遇到下面的状况。
那么怎开源阅览样做技能选型困惑了kotlin怎样读不少想要做混开的同学,终究Flutterwebview是什么东西的生态还不是非常老练,现成的处理计划和轮子并不多,并且还不必定好用,要么资源占用过高,要么侵入性太强。好在经过这几天的探求,总结出来了一套计划,供咱们学习参看,彼此交流。
按照国际惯例,我Kotlin先介绍一下现在市webviewapk下载场上的googleplay一些处理计划以及存在的问题。
本文章依据Flutter版别google服务结构:2.2 & Platform:Android
1.google空间Google官方(多引擎计划)
即每次运用一个新的FlutterEngine来烘托Widget树。尽管Flutter 2.0之后的创立Fluttekotlin实战rEngine的开支大大下降,可是依kotlin是什么意思然没有处理每个开源我国FlutterEngine是一个独自isWebViewolate,假定需求Flutter①和Flutter②之间交互数据的话google,将会非常费事。咱们相同无法保证他们之间不会进行数据交互,因此Pass。
2.大名鼎鼎的闲鱼flutter_boost(单引擎计划)
flutter_boost最近发布了3.0的bate版别,摒弃了2.0版别对引擎的侵入(赞!),可是仍然存在不少问题:
①:高居不下的webviewtest未封闭issues与回复不及时之间的对立(能够了解,竟然仍是有作业要做的)。
②:杂乱的规划,在呈现运用问题的时分,经过接口测验改flutgoogle空间ter_boost源码处理的本钱很高。
③:flutter方面耦合度较高,我必须运用flutter_boost供给的一系列Routwebviewapk下载e相关的google浏览器东西和Widget才华抵达混合栈跳转的效接口crc过错计数果,假定我往后想要替换结构,kotlin面试题那对代码的修正将是海量的。
于是乎成功把我劝退。
3.哈喽单google翻译车团队的flutter_thrio(单引擎计划)
该库的好坏作者现已说得很详接口细了,这儿就不再赘述,感兴趣的朋友能够进传送门亲身查看。
4.字节跳动团队的Isolate复用计划和腾讯心悦团队的TRouter计划
很可惜,现在这两个计划并google地球没有开源出来,但很可能字节团队的google地球计划的侵入性相当高Kotlin。
已然没有现成的计划,那就撸起袖子造一个,先来一个混合栈跳转的效果演示:
项目地址:githkotlin怎样读ub.com/wangkunhui/google地球…
那么现webview更新在开始把上面的功用完毕吧。
首要,要确认最终完毕的方针,然接口卡后一步步朝着方针去完善:
方针一:复用FlutterEngine,避免额开源矿工外的资源开支与FlutterEngigoogleplay安卓版下载ne之间的通讯本钱。
方针二:Flutter Widg接口crc过错计数et之间kotlin怎样读的跳google浏览器转无需经过Natigoogle翻译ve层控制(flutter_boost需求)。
方针三:每个翻开的Flutte开源节流是什么意思是什么r能且只能处理自己内部的栈,当时Flutter的Widget全部出栈接口卡后,退出当时Flutter。
方针四:支撑Flutter带参数翻googleplay安卓版下载开Native页面(回来值也能够支撑,但现在还未增加进去)。
依据这些方针规划出来的模型图如下:
上图是依次交叉翻开的5个Activity的栈信息示意图,能够分为三列,详细说明如下:
左边的是Activikotlin极简教程ty的栈信息,其间第二个和第四个挂载了Flutter,又分别翻开了几个Fluttekotlin下载r的Widget。
中心是FlutterEngine中的Wwebview更新idget栈示意图,由于复用FlutterEngine的原因,Widget A到kotlin教程Widget P都存在于一个栈中,而处在最底部的是一个空白的HostWidg接口测验et,不担任任何事务逻辑,其意图便是保证其上方的事务相关的Widget能正常被Pop出栈(由于Fluwebview下载tter NaGooglevigator的最终一个Widget是无法被Pop的)。
右侧是对中webview是什么东西心的FlutterEngine中Widget接口自动化栈的管线信息说明,便是那些Widget是相关在那些HostActivity实例上的,为的便是能够控制我对Widget进行退栈操作的时分,知道退到哪个Widget时需kotlin极简教程求finish掉相关的Activity。
假定上面的描绘不是很直观的话,那我举个栗子说明,我在HostActivity 实例2里翻开两个Fgoogleplaylutter页面kotlin实战,Widget O和Widg开源代码网站githubet P,当这两个Widget完毕自己的使命后,就要进行退出操作,当我退出Widget P时,界面就变成了Widget O,这是没问题的,然后我持续退出WIdget Okotlin面试题,假定不进行特别处理的话,FlutterEngine将会展现Widget N,这显着不webviewtest是咱们想要的。咱们预期的结果是此时要finis接口的效果h掉Hostgoogle商店Activity 实例2,展现NativeOneActivity,想要抵达这样的效果,就需求以为的把FlutterEngine 栈里边在不同HostActivity实例中显现的Widget进行特别的差异。
好了,理论作业现已做完了,接下来便是愉快的Cowebview最新版下载ding韶光,咱们面对使命清单有以下几个:
一、怎样对FlutterEnginegoogle进行复用?
二、Flutte接口是什么rActivity、FlutterFragment仍是FlutterView?
三、接口和笼统类的差异怎样监听Flut接口文档terEngine的栈改动信息?
四、怎样把监听到的栈信息同步到宿主Activity实例?
五、怎样处理宿主Activity和Flutter页面的同步?
第一个问题,首要实例化FlutterEngine:
/**
* 初始化FlutterEngine
* @param contexkotlin极简教程t 上下文
* @param block 初始化状况回调 0 不需求初始化 1 开始初始化 2 初始化google服务结构完毕
*/
@Synchronized
fun initFlutterEngine(context: Context, block: (status: Int) -&开源代码网站githubgt; Unit) {
//判别缓存已存在
if (!Fluttekotlin面试题rEnwebview下载gineCache.getInstance().contains(FLUTTER_ENGIwebviewtestNE)) {
block(1)
//初始化FlutterEnwebviewapk下载gine
var engine = FlutterEngine(context.applicationContext)
//初始化BasicMessageChannel
messagkotlin和javaeChannel接口英文 = BasicMessageChannel(
engine.dartExecutor,
FLUTTER_MIX_STACK_CHANNEL,
StringCodec.INSTANCE
)
//增加音讯监听
messageChannel?.setMessageHand开源阅览ler(messageHandler)
this.initCallback = blowebviewapk下载ck
//开始工作dart代码
engine.dartExecutor.executeDartEntrypoint(
DartExecutor.DartEntrypoint.createDefault()
)
//缓存FlutterEngine
FlutterEngineCachegoogleplay安卓版下载.getInstance().put(FLUTTER_ENKotlinGINE, engine)
} else {
block(0)
}
}
FlutterEngineCache开源代码网站github现已帮咱们封装好了FlutterEngine的缓存功用,不过要怎样运用这个缓存呢?
官方供给的FlutterActivity类中有一个withCachedEngine的静态办法,能够帮kotlin言语助咱们获取运用缓存的Intent实例webview组件,也能够承继FlutterActivity重写getCachedEngineId办法,抵达FlutterEngine复用的效果,直接建议FlutterActivity就能够加载Flutter页面,非常的简略便当,可是假定有一些稍微杂乱的场景时,FlutterActivity就有些不太够用了。
第二个问题,Flutter 2.0 为咱们供给了三种Flutter容器,分别是FlutterActivity(FlutterFragmentActivwebview烘托有什么用ity)、FlutterFragment开源软件和FlutterView,以满意咱们不同开源我国场景下的运用,从这三个类注释文档的丰盛程度上来看,官方是非常引荐咱们直接运用Flut开源是什么意思terActivity的。简略看下源码就能发现,不管是FlutterActivity仍是FLutterFragment,都是依据FlutterView完毕的。假定项目有指定的基类需求承继或许要完毕原生UI+Flutter UI的状况,或是想要更早的预热Flutter的Widget,FlutterView无疑会更灵敏一些,所以这儿我就选择运用了普通的Activity+Fluttegoogle空间rView,伪代码如下:
class HostActivity : AppCompatActivity(){
var flutterEngine //缓存接口英文中拿到的FlutterEngine
var flutterChannel // BasicMessageChannel 下面会有专门的介开源节流是什么意思是什么绍
var flutterView
onCreGoogleate(){
//在onCreate办法调用之初,就提前预热Flukotlin和javatterE开源我国ngine,能够使Widget加载更流转
flutterEngine.lifecycleChannel.appIsResumed()
//相同在onCreate中发送音讯给FluuterEngine,提前替换咱们要加载的Widget,办法有过渡效果
flutterChanne接口测验l.sendgoogle翻译Message(routePath)webview烘托有什么用
super.onCreate()
setContentView(flutterVi接口crc过错计数ew = createFlutt开源操作系统erVwebviewtestiew())
}
onResume(google空间){
super()
flutterEngine.lifecycleChannel.appIsResumed()
}
onPause(){
super()
flutterEnginewebview是什么东西.lifecyclegoogle空间Channel.appIsPaused()
}
onwebview烘托有什么用Destroy(){
super()
fluttergoogle谷歌查找主页View.detachFromFlutterEngine开源软件()
}
}
第三个问题,监听FlutterEwebview是什么意思ngine里Widget栈信息的改动,在MaterialApp初始化的时分,有一个navigatorObservers的参数,支撑咱们增加navigatorwebviewapk下载的改动信息(Navigator是Flutter供给的页面切换类)。
void main() {
//这儿运用了Get结构来演示,但这不是必须的
var getApKotlinp = GetMaterialApp(
in接口是什么itialRoute: RouterMapper.ROUTER_HOME接口自动化,
getPages: [
GetPage(
name: RouterMapper.ROUTER_HOST, //空白的HostView
page: () => Host(),
transition: Transition.rightToLeft),
...
],
navigatorObservers: [RouteNavigatorObserve接口crc过错计数r()],
);
runApp(getApp);
RouterHelper.registerApp(); /google服务结构/在这儿注册音讯监听
}
class R开源outeNavigatorObserver extends NavigatorObserver {
@override
void didPush(Route<dynamic> route, Route<dynamic>接口和笼统类的差异? previousRoute) {
//kotlin和java 有Widget入栈 能够从route中获取name信息并同步到Native
}
@override
void didPop(Route<webview下载dynamic&g开源操作系统t; route, Route<dynamic>?google谷歌查找主页 previousRoute) {
// 有Widget出栈 能够从route中获取name信息并同步到Native开源我国
}
@override
void didReplace({Route<dynamic>? newRoute, Route<dynawebview最新版下载micgoogle浏览器>? oldRoute}) {
// 新的Widget替换了前一个Wigoogle翻译dget 能够从newRoute&amwebview完成p;oldRoute中获取name信息并同步到Native
}
@override
void didRemove(Route<dynamic> route, Ro接口文档ute<dynamic>? previousRoute) {
// 一个Widget被remove了,一般不主张这么做
}
}
经过承继NavigatorObserver类并注册到navigkotlin是什么意思atorObservers中,咱们完毕了对FlutterEngine中路由信息改动的监听,那么接着来下一个问题,咱们怎样把kotlin言语音讯同步给Native?
**第四个问题,**Flutter供给了三种办法用来和webview是什么东西Nativwebview最新版下载e交互数据,分别是BasicMgoogle服务结构essageChannel,MethodChannel和EventChannel,其间前两个是能够双向传递数据的,EventChannel只支撑Native给Flutter传递数据,常用语系统音讯的一个告知。MethodChannel用来传webview完成递办法调用,BasicMessageChannel用webview组件来传二进制数据,更适合咱们的试用场景,接下来咱们需求在Flutter和Native层住的BasicMessageChannewebview最新版下载l用来数据的交互。
那咱们分别在Flutter和Native层创立BasicMessageChannel:
//Flutter
class RouterHelper {
//注册音讯通道
static final _routerMessageChannel =
Bas接口英文icMessageChannel<String开源节流是什么意思是什么?>("flutter_router_channel", StringCo接口文档dec());
static registerApp() {
//避免下面空异常
WidgetsFlutterBinding.ensureInitialized();
//注册音讯监kotlin下载听
_routerMessageChannel.setMessageHandler((String? mgoogle地球essage) async {
if (message != null) {
//native层传递过来的音讯
}
});
}
}
//Kotlin
fukotlin面试题n initMessageChannkotlin教程el(){
var messageChannel = BasicMessageChankotlin言语nel(
engine.dartExecutor,
"flutter_router_channel",
StringCodec接口卡.INSTANCE)
messageCha开源阅览nnekotlin教程l.setMessageHawebviewtestndler{ message, reply ->
//处理Flut接口的效果ter发送的音讯
}
}开源基金会
音讯的发送由BasicMessageChannel供给的send办法完毕,在上面的一个问题中,咱们现现已过监听Navigator来判别Flutter中页面的改动信息,接下来就要在监听办法中,把对应的信息发送到Native层进行处理,在Native层咱们能够笼统出来一个接口,让HostAct接口测验ivity结google束这接口,经过面向接口编程的办法,把音讯分发到当时生动的HostActivity中。而HostActivity中保护了一个栈来记载Flutter中栈信息的改动。
/**
* flutter路由改动回调
*/
interface RouteCallback {
//flutter route入栈音讯
fun on开源软件Push(route: String)
//flutter route出栈音讯
fun onPop(route: String)
//flutter roukotlin为什么盛行不起来te栈替换音讯
fun onReplace(newRoute: String接口的效果, oldRoute: String)
//flutter route被移除的音讯
fun onRemove(route: String)
//flutter央求翻开Native页面的音讯
fun routeNative(nativeRouWebViewte: String, params: HashMap&l接口是什么t;String, Any>? = null)
//flutter route出栈音讯
fun getLifecycleOwner(): LifecycleOwner
}
class HostActivity : AppCompatActivity(), RouteCallback {
//记载flutter的路由栈信息
p开源我国rivate val rokotlin和javauteStack: Stack<Strin开源是什么意思g> by lazy {
Stkotlin为什么盛行不起来ack()
}
//TODO RouteCallback接开源节流是什么意思是什么口的接口完毕办法,在办法中对routeStack进行入栈和出栈操作
}
最终一个问题接口的效果,咱们需求用户进行回来操作的时开源我国分,Widget页面要和HostActivity坚持同步,例如其webview更新时HostActivity只翻开了一个Widget,那么这个Widget退出的时分,HostActivity也要同步finish掉,即使FlutterEngine中还存在Google其他的Widget。咱们能够经过Hosgoogle空间tActivity中保护的routeStack来完毕。
override fun onBackPressed() {
//判别当时栈的长度,假定开源我国当时HostActivity栈的长度小于等于1,那么Activity就要finsih
if (rokotlin实战uteStack.size <= 1) {
super.onBa接口和笼统类的差异ckPressed()
flutterEnginkotlin是什么意思e.navigationChannel.popRoute()
}
//正常实行Navigawebview更新tor的pop操作
else {
flutterEngine.kotlin教程navigationChannel.popRoute()
}
}
当然还有一个问题需求开源阅览留神,webview最新版下载有些Widget的回来并不是经过回来键处理的,那咱们就google服务结构需对onPop办法进行一些特别处理:
overgoogle翻译ride fun onPop(route: Skotlin下载tring) {
//正常处理出栈逻辑
if (routeStack.isEmpty() &webviewapk下载amp;& !isFinishing) {
//假定现已全部出栈,则当时Ho开源基金会stActivity的事务已完毕
finish()
}
}
这样,就能把HostActivity和该宿主内翻开的WiKotlindget进行相关,做到一起进退,首要的逻辑完毕起来也不担任,也不需求运用任何第三方的结构,这样就开源节流是什么意思是什么有了很大的灵敏性,尤其是对Flutter来说,Flutter的生态还不是非常老练,避免运用侵入性过大的结构,也为往后技能的迭代接口的效果留有满意的空间。
缺点和缺乏
尽管经过对Flutter内栈信息改动的监听和经过Basi接口cM接口测验essageChannel的音讯同步来做好混合栈处理,可是现在仍然有一些问题需求处理。接口的效果
1:FlutteGoogler和Native页面的回来值监听,OneActivity翻开了一个HostActivity并想要在HostActivity退出的时分给OneAct开源基金会ivitgoogle空间y一个回来值,这个功用实例代码中还没有完毕,等有空持续完善该结构。
2:跨域回来的问题,这个“跨域”是我自己定义的一个名字,便是假定我翻开了两个HostActivity,第二个HostActivity经过Navigator的remove办法想要封闭掉第一个HostActivity中翻开的Widget,这个google浏览器是能够做到kotlin和java了,由于这两个HostActivity运用的是同一个FlutterEngine,假定呈现这种操作,那就会让第一个HostActivity的页面显现呈现问题。其实我在想,理想的webview完成混合处理结构应该是把google翻译每个翻开的Host开源Ac接口英文tivity作为一个WebView来看待,想要在第二个WebView中封闭第一个WebView里翻开的页面,这显着也是不太合适的。这种跨域回来是否需求支撑,也是一个值得考虑的问题。
好了,以上便是本篇文章的全部内容,开源阅览该计划现在还只是演示阶段,还没有完善到成为一个高可用的结构,只是为混合开发中处理混合栈供给了一个思路,假定咱们有什么更好的计划,欢迎多多交流~