一种页面导航方法、设备及可读存储介质

文档序号:1952355 发布日期:2021-12-10 浏览:13次 >En<

阅读说明:本技术 一种页面导航方法、设备及可读存储介质 (Page navigation method, equipment and readable storage medium ) 是由 邓国雄 杨闯 陈丹燕 高于钦 黄炼 林淙源 王腾宇 宋英鑫 李子豪 于 2021-09-17 设计创作,主要内容包括:本申请公开了一种页面导航方法、设备及可读存储介质,该方法包括以下步骤:根据页面跳转需求信息,从路由栈框架的Flutter侧和Native侧中确定调用方;其中,Flutter侧和Native侧均暴露具有相同路由栈上下文数据结构的路由栈信息,且在路由栈框架中每个引擎维护各自引擎上的路由栈上下文,Native侧维护路由栈框架中全端的路由栈上下文;从调用方对应的目标路由栈上下文中,查找与页面跳转需求信息对应的路由参数;利用路由参数,在路由栈框架中对应的Flutter侧和/或Native侧进行页面跳转导航。在本申请,不仅具有Flutter混合开发中的路由导航能力,还可在多引擎与局部视图上进行支持。(The application discloses a page navigation method, a device and a readable storage medium, wherein the method comprises the following steps: determining a calling party from a Router side and a Native side of a routing stack frame according to page jump requirement information; the routing stack frame comprises a Flutter side and a Native side, wherein the Flutter side and the Native side both expose routing stack information with the same routing stack context data structure, each engine in the routing stack frame maintains a routing stack context on each engine, and the Native side maintains the routing stack context at the whole end in the routing stack frame; searching a routing parameter corresponding to the page jump requirement information from a target routing stack context corresponding to a caller; and performing page jump navigation on the corresponding Flutter side and/or Native side in the routing stack frame by using the routing parameters. The method not only has the routing navigation capability in the hybrid development of the Flutter, but also can support on multiple engines and partial views.)

一种页面导航方法、设备及可读存储介质

技术领域

本申请涉及计算机应用技术领域,特别是涉及一种页面导航方法、设备及可读存储介质。

背景技术

混合开发指同一个App(手机软件)使用两种及其以上的技术栈进行页面开发。在混合开发中,需要实现不同技术栈的页面跳转。例如:Native(原生)与Flutter的混合开发,则需要满足:从Native页面中打开全屏Flutter页面;从Native页面中打开Flutter局部页面;在同一个Native页面中同时持有两个或两个以上FlutterView(Flutter视图),并支持携带局部视图的混合栈跳转。

在Flutter Boost中,由于Flutter引擎只能同时最多持有一个Flutter容器,因此在切换Flutter容器时必然会导致被切换的页面逻辑暂停,且App后台中Flutter逻辑无法执行。无法解决单页面内存在多个FlutterView的场景;没有提供路由栈维护方案,只能使用系统提供的默认栈导航。

在Flutter Thrio中,Flutter跳转Flutter只能使用Navigator,不支持打开一个新的Flutter容器,导致跳转动画与原生路由不一致,会导致割裂感;多引擎维护占用内存较大;无法解决单页面内存在局部FlutterView的场景,也不支持Flutter Fragment。

综上所述,以上两种方案仅仅提供了Flutter混合开发中的路由导航能力,在多引擎与局部视图上支持并不完备,也没有健全的路由栈维护机制。

发明内容

本申请的目的是提供一种页面导航方法、设备及可读存储介质,使得路由栈维护有序,不仅具有Flutter混合开发中的路由导航能力,还可在多引擎与局部视图上进行支持。

为解决上述技术问题,本申请提供如下技术方案:

一种页面导航方法,包括:

接收并解析页面跳转请求,得到页面跳转需求信息;

根据所述页面跳转需求信息,从路由栈框架的Flutter侧和Native侧中确定调用方;其中,所述Flutter侧和所述Native侧均暴露具有相同路由栈上下文数据结构的路由栈信息,且在所述路由栈框架中每个引擎维护各自引擎上的路由栈上下文,所述Native侧维护所述路由栈框架中全端的路由栈上下文;

从所述调用方对应的目标路由栈上下文中,查找与所述页面跳转需求信息对应的路由参数;

利用所述路由参数,在所述路由栈框架中对应的Flutter侧和/或Native侧进行页面跳转导航。

优选地,还包括:

在所述路由栈框架中,将无界面引擎作为共享数据的中转站,以实现引擎间通信。

优选地,所述接收并解析页面跳转请求,得到页面跳转需求信息,包括:

接收所述页面跳转请求;

若所述页面跳转请求为页面调用请求,则解析所述页面调用请求,得到所述页面跳转需求信息;其中,所述页面跳转需求信息包括调用方和调用页面。

优选地,利用所述路由参数,在所述路由栈框架中对应的Flutter侧和/或Native侧进行页面跳转导航,包括:

若所述调用方为所述Native侧,且所述调用页面已注册,则利用所述Native侧并结合所述目标路由栈上下文,执行所述调用页面的页面类型对应的页面打开流程。

优选地,利用所述Native侧并结合所述目标路由栈上下文,执行所述调用页面的页面类型对应的页面打开流程,包括:

若所述调用页面的页面类型为Native页面,则利用所述Native侧,将所述目标路由栈上下文中的索引顺序置1,并打开所述调用页面,将所述调用页面入所述Native侧的路由栈中,并触发所述Native侧的事件钩子。

优选地,利用所述Native侧并结合所述目标路由栈上下文,执行所述调用页面的页面类型对应的页面打开流程,包括:

若所述调用页面的页面类型为Flutter页面,则利用所述Native侧,将所述目标路由栈上下文中的索引顺序字段置1,通过所述目标路由栈上下文中的引擎标识字段,并将所述调用页面的页面信息从所述引擎标识字段对应引擎的通信通道传递给所述Flutter侧的对应引擎,以便所述Flutter侧将所述页面信息入自身的路由栈,初始化一个Flutter容器,并打开所述Flutter容器,渲染对应引擎上的所述调用页面,触发事件钩子,并向所述Native侧发送所述调用页面已成功打开的通知消息;

在所述Native接收到所述通知消息后,利用所述Native侧,将所述调用页面入所述Native侧的路由栈,并触发事件钩子。

优选地,所述利用所述路由参数,在所述路由栈框架中对应的Flutter侧和/或Native侧进行页面跳转导航,包括:

若所述调用方为所述Flutter侧,且所述调用页面已注册,则利用所述Flutter侧,执行所述调用页面的页面类型对应的页面打开流程。

优选地,所述利用所述Flutter侧并结合所述目标路由栈上下文,执行所述调用页面的页面类型对应的页面打开流程,包括:

若所述调用页面的页面类型为Native页面,则利用所述Flutter侧,将所述目标路由栈上下文中的索引顺序字段置1,获取对应引擎的引擎标识,并利用所述引擎标识对应的通信通道,将所述调用页面的页面消息发送给所述Native侧,以便所述Native侧收到所述页面消息后,打开所述调用页面,并将所述调用页面入所述Native侧的路由栈,触发所述Native侧的事件钩子,并向所述Native侧发送所述调用页面已成功打开的通知消息;

在所述Flutter侧接收到所述通知消息后,将所述调用页面入所述Flutter侧的路由栈,并触发所述Flutter侧的事件钩子。

优选地,所述利用所述Flutter侧并结合所述目标路由栈上下文,执行所述调用页面的页面类型对应的页面打开流程,包括:

若所述调用页面的页面类型为Flutter页面,则所述Flutter侧,判断所述调用页面是否对应当前Flutter页面的当前引擎;

若所述调用页面对应所述当前引擎,则利用所述Flutter侧并结合所述目标路由栈上下文,采用当前引擎对应的当前Flutter容器打开所述调用页面,或采用新Flutter容器打开所述调用页面;

若所述调用页面未对应所述当前引擎,则利用所述Flutter侧并结合所述目标路由栈上下文,采用新Flutter容器打开所述调用页面。

优选地,所述利用所述Flutter侧并结合所述目标路由栈上下文,执行所述调用页面的页面类型对应的页面打开流程,包括:

若所述调用页面的页面类型为Flutter局部视图,则初始化一个Flutter容器,并将所述Flutter容器添加至父容器中;

调用所述Flutter容器提供的路由导航方法,并传入所述Flutter局部视图对应所述目标路由栈上下文中的引擎标识与url及局部页面的标识字段;

调用所述引擎标识对应的引擎的打开方法,以便通知所述Flutter侧打开一个Flutter页面。

优选地,所述接收并解析页面跳转请求,得到页面跳转需求信息,包括:

接收所述页面跳转请求;

若所述页面跳转请求为页面关闭请求,则解析所述页面关闭请求,得到所述页面跳转需求信息。

优选地,利用所述路由参数,在所述路由栈框架中对应的Flutter侧和/或Native侧进行页面跳转导航,包括:

若所述目标页面为Native页面,则利用所述Native侧的路由栈关掉最后一个路由信息,并获取所述路由信息中所述目标路由栈上下文的局部页面的标识字段;

利用所述局部页面的标识字段,判断当前页面是否嵌套了Flutter子视图;

如果是,则监听技术框架自定义的Flutter容器KantFlutterViewController销毁事件,在监听到所述Flutter子视图被销毁的情况下,检索Flutter引擎管理器维护的多引擎关系对象,取得所述多引擎关系对象对应的引擎标识,利用所述Native侧通知所述引擎标识对应的Flutter引擎关掉各自对应的最后一个路由信息,所述Native侧将关掉的路由信息和倒数第二个路由信息作为入参调用事件钩子通知;

如果否,则利用所述Native侧取最后一个路由信息的引擎标识,通知对应的引擎标识的Flutter引擎关掉该Flutter引擎对应的最后一个路由信息,所述Native侧将关掉的路由信息和倒数第二个路由信息作为入参调用事件钩子通知。

优选地,所述利用路由栈框架中与所述页面跳转需求信息对应的目标路由栈上下文,实现与所述页面跳转需求对应的页面跳转导航,包括:

若所述目标页面为Flutter页面,则利用所述Flutter侧关掉当前引擎上最后一个路由信息,获取所述路由信息中所述目标路由栈上下文的局部页面的标识字段;

利用所述局部页面的标识字段判断当前Flutter页面是否为局部视图;

如果是,则利用Flutter侧关掉的路由信息所对应引擎及该引擎上倒数第二个路由信息作为入参调用事件通知钩子;

如果否,则通过请求所述Native侧,获取所述Native侧倒数第二个页面的路由信息,并通知所述Native侧关掉所述Native侧最后一个路由信息,所述Flutter侧将关掉的路由信息与获取到的倒数第二个路由信息作为入参调用事件通知钩子。

一种电子设备,包括:

存储器,用于存储计算机程序;

处理器,用于执行所述计算机程序时实现上述页面导航方法的步骤。

一种可读存储介质,所述可读存储介质上存储有计算机程序,所述计算机程序被处理器执行时实现上述页面导航方法的步骤。

应用本申请实施例所提供的方法,接收并解析页面跳转请求,得到页面跳转需求信息;根据页面跳转需求信息,从路由栈框架的Flutter侧和Native侧中确定调用方;其中,Flutter侧和Native侧均暴露具有相同路由栈上下文数据结构的路由栈信息,且在路由栈框架中每个引擎维护各自引擎上的路由栈上下文,Native侧维护路由栈框架中全端的路由栈上下文;从调用方对应的目标路由栈上下文中,查找与页面跳转需求信息对应的路由参数;利用路由参数,在路由栈框架中对应的Flutter侧和/或Native侧进行页面跳转导航。

在路由栈框架中Flutter侧和Native侧均暴露具有相同路由栈上下文数据结构的路由栈信息且有着对应的引擎进行维护。在有页面跳转导航需求时,便可基于相应的路由栈上下文实现智能的页面跳转导航。具体的,接收并解析页面跳转请求后,可以得到跳转需求信息。然后,基于跳转需求信息明确调用方,从该调用方对应的目标路由器栈上下文中查找出与该跳转需求信息匹配的路由参数。利用路由参数,在路由栈框架中对应的Flutter侧和/或Native侧,便可实现能够满足该页面跳转需求信息对应的页面跳转导航。可见,在本申请,基于目标路由栈上下文,不仅具有Flutter混合开发中的路由导航能力,还可在多引擎与局部视图上进行支持。

相应地,本申请实施例还提供了与上述页面导航方法相对应的电子设备和可读存储介质,具有上述技术效果,在此不再赘述。

附图说明

为了更清楚地说明本申请实施例或相关技术中的技术方案,下面将对实施例或相关技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。

图1为本申请实施例中一种页面导航方法的实施流程图;

图2为本申请实施例中一种引擎间通信示意图;

图3为本申请实施例中一种Native页面打开全屏Flutter页面的场景示意图;

图4为本申请实施例中一种点击Native直播间中图标来打开一个Flutter半屏页的示意图;

图5为本申请实施例中一种在Native的直播间内,红包模块和挂件模块由两个FlutterView开发而成的示意图;

图6为一种导航路由逻辑示意图;

图7为另一种导航路由逻辑示意图;

图8为本申请实施例中一种导航路由逻辑示意图;

图9为本申请实施例中一种Flutter View作为多个Tab页来渲染的示意图;

图10为本申请实施例中一种多局部视图场景下的随时出入栈的混合路由栈维护能力的示意图;

图11为本申请实施例中一种路由栈示意图;

图12a为本申请实施例中另一种路由栈全局示意图;

图12b为本申请实施例中另一种路由栈局部1示意图;

图12c为本申请实施例中另一种路由栈局部2示意图;

图12d为本申请实施例中另一种路由栈局部3示意图;

图13为本申请实施例中一种页面导航装置的结构示意图;

图14为本申请实施例中一种电子设备的结构示意图;

图15为本申请实施例中一种电子设备的具体结构示意图;

图16为本申请实施例中一种调用方为Native侧的页面打开流程示意图;

图17为本申请实施例中一种调用方为Flutter侧的页面打开流程示意图;

图18为本申请实施例中一种pop页面打开流程示意图。

具体实施方式

为了使本技术领域的人员更好地理解本申请方案,下面结合附图和具体实施方式对本申请作进一步的详细说明。显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。

请参考图1,图1为本申请实施例中一种页面导航方法的流程图,该方法包括以下步骤:

S101、接收并解析页面跳转请求,得到页面跳转需求信息。

其中,页面跳转请求可以具体为混合开发的APP发送的页面跳转请求。例如,当监测用户在APP中点击页面中的链接或开关按钮等,需要打开/或关闭某个/些页面(如全屏页面/或具备视图或有链接功能的局部视图)时,确定收到页面跳转请求,根据用户的具体操作行为确定页面跳转需求。当然,该页面跳转请求也可以具体为携带了页面跳转需求信息的请求,对该请求进行对应解析,便可直接获得页面跳转需求信息。

S102、根据页面跳转需求信息,从路由栈框架的Flutter侧和Native侧中确定调用方。

其中,Flutter侧和Native侧均暴露具有相同路由栈上下文数据结构的路由栈信息,且在路由栈框架中每个引擎维护各自引擎上的路由栈上下文,Native侧维护路由栈框架中全端的路由栈上下文。

S103、从调用方对应的目标路由栈上下文中,查找与页面跳转需求信息对应的路由参数。

具体的,路由栈框架中Flutter侧和Native侧均暴露具有相同路由栈上下文数据结构的路由栈信息;在路由栈框架中每个引擎维护各自引擎上的路由栈上下文(其中,上下文可具体指页面),Native侧维护路由栈框架中全端的路由栈上下文。

在本申请中的路由栈上下文数据结构(为可变的变量名,如KantRouteSettings)可具体包括以下字段:

字段1、index:int,即索引顺序字段,当前Flutter页面所在的container(容器)内的索引;

字段2、url:String,即字符串类型的路由名字段,如url,也就是route注册的url;

字段3、uniqueId:String,即字符串类型的页面标识字段,如uniqueId,也就是页面的唯一标识符;

字段4、entrypoint:String(字符串类型的引擎标识符字段,例如引擎标识),页面所在引擎的标识符;

字段5、局部页面的标识字段:Bool,即,布尔类型的局部视图标识符,如局部页面的标识字段,表明是否为嵌套页面;

字段6、params:Object,即字典类型的页面额外参数,如params,对应页面参数。

需要注意的是,在本申请中对以上6个字段的先后顺序等均不做限定。为了便于查找,还可将以上6个字段划分为名称部分如name和参数部分如arguments,其中,name可对应包括上述字段1和字段2,arguments对应包括上述字段3至字段6。

优选地,为了便于确定页面的类型,及是否隐藏系统导航栏,还可以设置:

字段7、platform:String,即,字符串类型的平台字段,如platform,表明该页面是“flutter”或是“native”;

字段8、hideNavBar:Bool,即布尔类型的隐藏导航标识符,如hideNavBar,表明是否隐藏系统导航栏。

字段7和字段8可对应于arguments。

一般地,Flutter路由栈框架分为Android侧,iOS侧与Dart侧,为了便于描述,下文不区分Android与iOS,而将这二者统一简称Native侧,由于在本申请中混合开发以Flutter开发为例,因而Dart侧对应Flutter侧(当然,在本申请中的其他实施例中,Flutter侧可以为其他页面开发框架/技术)。

上述路由栈上下文数据结构不仅仅要在Dart侧实现一个Model(数据模型,如数据模型)来维护,在Native侧也同样要实现一份等同的Model,以便在页面跳转时三端能及时维护各自的路由栈。

具体的,在Dart侧,暴露了一个路由栈信息列表属性,如KantSettingsList,该属性是一个数组结构为泛型为路由栈页面的数据结构,如KantRouteSettings,是一个一维数组,用于存放入栈的路由信息,来作为路由栈上下文,此外还暴露了一个引擎标识,这是Engine的标识。

在Native侧,同样的暴露了一个KantSettingsList属性,含义同Dart侧,作为路由栈上下文供业务侧取用。

需要说明是,路由信息路设计了字段index,这个并非其他框架里当前页面所在路由栈的索引(如果要取当前页面所在路由栈的索引,直接配合KantSettingsList就可以得到这个索引),而是指当前Flutter页面所在的容器的索引,如果Native页面默认为1,这个字段的用途在于开关iOS侧的手势返回。因为Flutter的手势优先级小于iOS系统手势,如果使用了Navigator(Flutter的路由类库)而不做任何手势拦截处理,那么Flutter的侧滑返回手势则永远被iOS的系统手势覆盖。

在本申请中,多引擎管理与多引擎路由栈的维护如下:

首先是多引擎管理,在路由栈框架内部维护了一个页面注册方法(如registerRoute),一个引擎管理类库(如Flutter引擎管理器),类库中维护了一个各引擎的内容管理变量,如KantFlutterEngineContext。key(键)值为引擎标识,value(值)为Flutter容器数组,如Array<KantFlutterViewControoler>,用来存放当前引擎上相关的FlutterViewControllers,以便维护引擎切换挂载FlutterViewController。另外,框架还提供了一个引擎启动方法(startup)。

框架管理多引擎流程如下:

1、框架初始化,Flutter引擎管理器会初始化一个引擎数组FlutterEngines和一个Map(KantFlutterEngineContext);

2、Dart侧与Native侧分别按需调用registerRoute方法注册页面并指定页面所在的引擎;

3、Native侧若干个指定名字的启动引擎,注册到Flutter引擎管理器上。

即,本申请封装了一个Flutter引擎管理器来管理多引擎和引擎上的Flutter容器。

其次是多引擎路由栈的维护,框架要求每个引擎需要维护各自引擎上的路由栈上下文,而Native侧则需要维护整个框架的全端的路由栈上下文,即如果有n个引擎,那么就有n+1个KantSettingsList需要维护。

多引擎路由栈维护策略如下:

1、Flutter的路由栈上下文字段,如settingsList,只维护当前引擎的路由;

2、Native的路由栈上下文字段,如settingsList维护所有引擎的路由;

3、RouteSettings维护了一个index,该值表示这个route(路由)页面(路由栈中页面)是当前FlutterViewController内的第几个页面;

4、push(打开)一个native页面会把这个native页面信息放在最近的一个引擎上;

5、Flutter局部视图情境下,Naitve的路由栈维护的是当前FlutterView所在的Native页面信息。

需要注意的是,携带多局部视图的场景下,本方案依然支持Navigator与使用新的FlutterViewController打开页面,并且在push之后,即打开页面后能依然保留前一个页面的状态。

如此,在获得跳转需求信息之后,便可以通过查询目标路由栈上下文,从而得到对应的路由参数,该路由参数可以具体对应上述路由栈上下文数据结构中所包括的具体字段的参数。

基于上述路由栈上下文结构而设置路由栈,以及上述路由栈维护策略,可以实现页面跳转导航。也就是说,利用路由栈框架中与页面跳转需求信息对应的路由参数,可以实现与页面跳转需求对应的页面跳转导航。即可以实现页面的打开跳转和关闭跳转。

S104、利用路由参数,在路由栈框架中对应的Flutter侧和/或Native侧进行页面跳转导航。

具体的,对于业务侧只需要传页面名就可以打开页面了,不需要业务侧额外实现打开方法和关闭方法。如Flutter Boost就需要业务侧实现两个方法才能打开或关闭页面。

应用本申请实施例所提供的方法,接收并解析页面跳转请求,得到页面跳转需求信息;根据页面跳转需求信息,从路由栈框架的Flutter侧和Native侧中确定调用方;其中,Flutter侧和Native侧均暴露具有相同路由栈上下文数据结构的路由栈信息,且在路由栈框架中每个引擎维护各自引擎上的路由栈上下文,Native侧维护路由栈框架中全端的路由栈上下文;从调用方对应的目标路由栈上下文中,查找与页面跳转需求信息对应的路由参数;利用路由参数,在路由栈框架中对应的Flutter侧和/或Native侧进行页面跳转导航。

在路由栈框架中Flutter侧和Native侧均暴露具有相同路由栈上下文数据结构的路由栈信息且有着对应的引擎进行维护。在有页面跳转导航需求时,便可基于相应的路由栈上下文实现智能的页面跳转导航。具体的,接收并解析页面跳转请求后,可以得到跳转需求信息。然后,基于跳转需求信息明确调用方,从该调用方对应的目标路由器栈上下文中查找出与该跳转需求信息匹配的路由参数。利用路由参数,在路由栈框架中对应的Flutter侧和/或Native侧,便可实现能够满足该页面跳转需求信息对应的页面跳转导航。可见,在本申请,基于目标路由栈上下文,不仅具有Flutter混合开发中的路由导航能力,还可在多引擎与局部视图上进行支持。

需要说明的是,基于上述实施例,本申请实施例还提供了相应的改进方案。在优选/改进实施例中涉及与上述实施例中相同步骤或相应步骤之间可相互参考,相应的有益效果也可相互参照,在本文的优选/改进实施例中不再一一赘述。

在本申请中的一种具体实施方式中,考虑到引擎之间无法直接进行通信,在本实施例中提出在路由栈框架中,将无界面引擎作为共享数据的中转站,以实现引擎间通信。

请参考图2,图2为本申请实施例中一种引擎间通信示意图。

其中,无界面引擎(即默认引擎)作为Store(存储空间)中转站,使用原生能力Dispatch(派遣/分发)来下发共享数据到不同引擎之中。

在图2中Native(图示原生侧数据模型)与三个引擎建立了三个通道。如图2所示,引擎3是无界面引擎,专门用来管理数据,是模型中的Store。而Native提供的DataModel(数据模型)用于管理Store中的数据来做数据分发,即作为模型中的Dispatch。Flutter视图1和Flutter视图2分属于两个不同的引擎,如果Flutter视图1想要给Flutter视图2发送状态消息,则需要将发送的数据通过Dispatch维护到Store中,如果Store数据发生了变换(即状态改变,需要通知Flutter视图2)则会触发Dispatch将变换的数据发送到Flutter视图2。

在本申请中的一种具体实施方式中,上述步骤S101接收并解析页面跳转请求,得到页面跳转需求信息,可具体包括:

步骤一、接收页面跳转请求;

步骤二、若页面跳转请求为页面调用请求,则解析页面调用请求,得到页面跳转需求信息;其中,页面跳转需求信息包括调用方和调用页面。

为便于描述,下面将上述三个步骤结合起来进行说明。

也就是说,所接收的页面跳转请求具体为页面调用请求,即需要打开页面,解析该页面调用请求,最终可以得到包括调用方和调用页面。其中,调用方可以具体为Native侧,也可以具体为Flutter侧,调用页面即指需要被打开的页面,该调用页面可以为Native页面,也可以为Flutter。

具体的,请参考图16,若调用方为Native侧,且调用页面已注册,则利用Native侧并结合目标路由栈上下文,执行调用页面的页面类型对应的页面打开流程。

下面以调用页面的页面类型分别为Native页面和Flutter页面,页面跳转导航进行说明:

若调用页面的页面类型为Native页面,则利用Native侧,将目标路由栈上下文中的索引顺序字段置1,并打开调用页面,将调用页面入Native侧的路由栈中,并触发Native侧的事件钩子。

若调用页面的页面类型为Flutter页面,则利用Native侧,将目标路由栈上下文中的索引顺序字段置1,通过目标路由栈上下文中的引擎标识字段,并将调用页面的页面信息从引擎标识字段对应引擎的通信通道传递给Flutter侧的对应引擎,以便Flutter侧将页面信息入自身的路由栈,初始化一个Flutter容器,并打开Flutter容器,渲染对应引擎上的调用页面,触发事件钩子,并向Native侧发送调用页面已成功打开的通知消息;

在Native接收到通知消息后,利用Native侧,将调用页面入Native侧的路由栈,并触发事件钩子。

具体的,请参考图17,若调用方为Flutter侧,且调用页面已注册,则利用Flutter侧,执行调用页面的页面类型对应的页面打开流程。

下面以调用页面的页面类型分别为Native页面和Flutter页面,页面跳转导航进行说明:

若调用页面的页面类型为Native页面,则利用Flutter侧,将目标路由栈上下文中的索引顺序字段置1,获取对应引擎的引擎标识,并利用引擎标识对应的通信通道,将调用页面的页面消息发送给Native侧,以便Native侧收到页面消息后,打开调用页面,并将调用页面入Native侧的路由栈,触发Native侧的事件钩子,并向Native侧发送调用页面已成功打开的通知消息;

在Flutter侧接收到通知消息后,将调用页面入Flutter侧的路由栈,并触发Flutter侧的事件钩子。

若调用页面的页面类型为Flutter页面,则Flutter侧,判断调用页面是否对应当前Flutter页面的当前引擎;

若调用页面对应当前引擎,则利用Flutter侧并结合目标路由栈上下文,采用当前引擎对应的当前Flutter容器打开调用页面,或采用新Flutter容器打开调用页面;

若调用页面未对应当前引擎,则利用Flutter侧并结合目标路由栈上下文,采用新Flutter容器打开调用页面。

若调用页面的页面类型为Flutter局部视图,则初始化一个Flutter容器,并将Flutter容器添加至父容器中;

调用Flutter容器提供的路由导航方法,并传入Flutter局部视图对应目标路由栈上下文中的引擎标识与url及局部页面的标识字段;

调用引擎标识对应的引擎的打开方法,以便通知Flutter侧打开一个Flutter页面。

为便于理解,下面针对不同情境下的push页面的导航过程进行详细说明:

通常,打开页面包括但不限于以下5种不同的场景:

场景一、Flutter→Native;

场景二、Flutter→Flutter(单一容器内跳转);

场景三、Flutter→Flutter(打开一个新的容器);

场景四、Native→Flutter;

场景五、Native→Native。

下面从两个调用方的角度来对push(打开)页面进行阐述:

角度1:若调用方是原生侧:

首先,根据platform字段判断被打开的页面(即调用页面)是Flutter页面还是原生页面。

需要注意的是,在实际应用中,原生侧可以调用打开页面的方法(push方法)拿到被打开页面的路由名之后可以查路由注册表,根据表内容即可判断这个页面的是Flutter页面还是Native页面。

Native侧查自己维护的路由表,检查该页面是否被注册;

如果被打开的页面不是路由表中的页面,则结束流程;

如果被打开的页面是路由表中的页面;

如果被打开的页面是路由表中注册的Native页面,即对应上述场景Native→Native;

将被打开页面的index设置为1;

打开Native页面,并将该页面入Native的栈,同时触发Native侧的事件钩子;

Native检索Native侧维护的路由栈,反向查找,找到最近的一个Flutter页面信息的引擎标识字段;

如果没有找到Flutter页面,说明并非混合路由栈,无需通知Flutter侧;

如果找到了Flutter页面,通过它的引擎标识字段获取该引擎标识对应的引擎;

如果引擎没有启动,先启动引擎,在该引擎启动成功的回调中获取通信通道;

如果引擎启动了,直接获取该引擎的通信通道;

通过通信通道,将该页面的信息传递给Flutter侧的对应引擎,Flutter侧收到事件后将页面信息入栈,并触发事件钩子,结束流程。

如果被打开的页面是路由表中注册的Flutter页面,即对应上述场景Native→Flutter;

将被打开页面的index设置为1;

Native通过该Flutter页面的引擎标识字段并获取该引擎标识对应引擎;

如果引擎没有启动,先启动引擎,在在引擎启动成功的回调中获取通信通道;

如果引擎启动了,直接获取该引擎的通信通道;

通过该通道,将该页面的信息传递给Flutter侧的对应引擎,Flutter侧收到事件后将页面信息入栈;

初始化一个Flutter容器,并打开该容器,渲染引擎上的Flutter页面,最后触发事件钩子,并告知Native侧打开成功了;

Native收到消息后,将该页面入Native的栈,同时触发Native侧的事件钩子,结束流程。

角度2:若调用方Flutter侧:

若调用方Flutter侧,则引擎一定是启动状态,可根据platform字段判断被打开的页面(调用页面)是Flutter页面还是原生页面;

需要注意的是,Flutter可以去查原生侧维护的路由注册表判断被打开的页面是Flutter页面还是原生页面。

通过通信通道获取Native侧维护的路由表,查路由表,检查该页面是否被注册;

如果被打开的页面不是路由表中的页面,结束流程。

如果被打开的页面是路由表中的页面;

如果被打开的页面是表中注册的Native页面,即对应上述场景Flutter→Native;

将被打开页面的index设置为1;

Flutter页面获取该引擎的引擎标识,找到对应的通信通道,发送页面消息给Native侧;

Native收到消息后,打开该Native页面,并入Native的栈,之后触发Native事件钩子,并告知Flutter侧打开成功;

Flutter收到消息之后,将页面入栈,并触发Flutter侧事件钩子,结束流程。

如果被打开的页面是表中注册的Flutter页面,获取当前引擎上的路由栈,判断该页面是否在当前引擎上;

如果是同一个引擎的页面,那么再判断业务侧是否希望使用新的容器来打开Flutter页面;

使用当前Flutter容器打开:

获取当前Flutter页面的index,并将被打开页面的index设置为index+1;

Flutter将页面入信息栈,并触发事件钩子;

Flutter获取当前引擎的通信通道,告知Native侧页面打开成功了;

Native收到消息后,将该页面入Native的栈,同时触发Native侧的事件钩子,结束流程。

使用新的Flutter容器打开:

将被打开页面的index设置为1;

Flutter将页面入信息栈;

初始化一个Flutter容器,并打开该容器,渲染引擎上的Flutter页面,触发事件钩子;

Flutter获取当前引擎的通信通道,告知Native侧页面打开成功了;

Native收到消息后,将该页面入Native的栈,同时触发Native侧的事件钩子,结束流程。

如果不是同一个引擎的页面,需要打开一个新的容器来展示,即Flutter→Flutter(打开一个新的容器);

将被打开页面的index设置为1;

通过当前页面信息和被打开页面的Flutter信息的两个引擎标识,告知Native获取两条通信通道;

利用这两条通信通道,Flutter侧通过Native作为中转,将被打开的页面信息发送给对应的Flutter引擎;

对应的Flutter引擎将页面入栈,并初始化一个Flutter容器,并打开该容器,渲染引擎上的Flutter页面,触发事件钩子;

利用通信通道告知Native侧页面打开成功了;

Native收到消息后,将该页面入Native的栈,同时触发Native侧的事件钩子,结束流程。

需要注意的是,还有一种特殊情况,即被展现的页面是Flutter局部视图,流程如下,这个流程如下:

初始化一个技术框架自定义的Flutter容器,如KantFlutterViewController(一个自定义的封装的Flutter容器),并指定其大小和位置,添加进父容器中;

调用KantFlutterViewController提供的自己实现的一个打开Flutter页面的方法,如openRoute,传入要被展示的Flutter局部视图的引擎标识与url以及局部页面的标识字段(其值固定为1);

判断App中是否已经启动了对应引擎标识的引擎;

如果没有,先启动引擎,在引擎启动成功的回调中调用push方法;

如果启动了,那么直接调用push方法;

push方法会通知Flutter侧去打开一个Flutter页面,即对应上述Flutter→Flutter(单一容器内跳转)场景,结束流程。

在本申请中的一种具体实施方式中,上述步骤S101接收并解析页面跳转请求,得到页面跳转需求信息,包括:

步骤一、接收页面跳转请求;

步骤二、若页面跳转请求为页面关闭请求,则解析页面关闭请求,得到页面跳转需求信息。

页面关闭请求,即对应需要POP(关闭)某个页面时,所触发/接收到的请求。其中,目标页面即指对应关闭的页面,该页面可以是全屏页面也可以是局部视图。在本实施例中,关闭时的需求信息并不需要调用方传入目标页面的信息。因为框架自己可以根据路由栈知道上一个页面的信息是什么。

请参考图18,该目标页面可以为Native页面,也可以为Flutter。

具体的,若目标页面为Native页面,则利用Native侧的路由栈关掉最后一个路由信息,并获取路由信息中目标路由栈上下文的局部页面的标识字段;

利用局部页面的标识字段,判断当前页面是否嵌套了Flutter子视图;

如果是,则监听技术框架自定义的Flutter容器,如KantFlutterViewController销毁事件,在监听到Flutter子视图被销毁的情况下,检索Flutter引擎管理器维护的多引擎关系对象,取得多引擎关系对象对应的引擎标识,利用Native侧通知引擎标识对应的Flutter引擎关掉各自对应的最后一个路由信息,Native侧将关掉的路由信息和倒数第二个路由信息作为入参调用事件钩子通知;

如果否,则利用Native侧取最后一个路由信息的引擎标识,通知对应的引擎标识的Flutter引擎关掉该Flutter引擎对应的最后一个路由信息,Native侧将关掉的路由信息和倒数第二个路由信息作为入参调用事件钩子通知。

若目标页面为Flutter页面,则利用Flutter侧关掉当前引擎上最后一个路由信息,获取路由信息中目标路由栈上下文的局部页面的标识字段;

利用局部页面的标识字段判断当前Flutter页面是否为局部视图;

如果是,则利用Flutter侧关掉的路由信息所对应引擎及该引擎上倒数第二个路由信息作为入参调用事件通知钩子;

如果否,则通过请求Native侧,获取Native侧倒数第二个页面的路由信息,并通知Native侧关掉Native侧最后一个路由信息,Flutter侧将关掉的路由信息与获取到的倒数第二个路由信息作为入参调用事件通知钩子。

下面将各种类型的目标页面关闭过程进行综合说明。具体的,pop目标页面时,路由栈维护逻辑如下:

判断目标页面的platform字段,看其是Native页面还是Flutter页面;

如果是Native页面:

Native路由栈pop掉最后一个路由信息,并取得其局部页面的标识字段;

判断局部页面的标识字段,即当前页面是否嵌套了Flutter子视图;

如果局部页面的标识字段为true(真),则执行以下步骤:

监听KantFlutterViewController销毁事件,如果被销毁了,就去检索Flutter引擎管理器维护的多引擎关系对象KantFlutterEngineContext,取得这些KantFlutterViewController对应的引擎标识;

Native通知这些引擎标识对应的Flutter引擎pop(推出)它们的最后一个路由信息;

Native将pop(推出)的路由信息和倒数第二个路由信息作为入参调用事件钩子通知,结束流程。

如果局部页面的标识字段为false(假),则执行以下步骤:

Native取最后一个路由信息的引擎标识;

Native通知对应的引擎标识的Flutter引擎pop掉其最后一个路由信息;

Native将pop(推出)的路由信息和倒数第二个路由信息作为入参调用事件钩子通知,结束流程。

如果是Flutter页面:

Flutter侧pop(推出)当前引擎上最后一个路由信息,取得其局部页面的标识字段字段,判断当前Flutter页面是否为局部视图;

如果局部页面的标识字段为true,则Flutter侧将pop掉的路由信息与该引擎上倒数第二个路由信息作为入参调用事件通知钩子,结束流程(因为Native侧不维护Flutter的局部视图信息,而现在pop的又是Flutter页面,仅Flutter侧有该路由信息)。

如果局部页面的标识字段为false(假),则Flutter侧请求Native侧,获取Native侧倒数第二个页面的路由信息(因为上一个页面可能不是本引擎的,这种非局部视图场景下,从Native侧获取上个路由信息才是准确的);

Flutter通知原生侧关闭Native侧最后一个路由信息;

Flutter侧将pop掉的路由信息与获取到的倒数第二个路由信息作为入参调用事件通知钩子,结束流程。

维护完整框架的路由栈上下文之后,业务侧可以按需取用,也可随时出栈入栈,同时在监听生命周期与路由事件时框架才可提供准确的页面信息。

为了便于本领域技术人员更好地理解本申请实施例所提供的页面导航方法所对应的技术效果,下面结合具体的应用场景和相关技术示例,对页面导航方法的技术效果进行详细说明。

混合栈:即混合路由导航栈,同一个App中存在不止一种技术栈开发的页面的场景下,需要使用混合栈来管理应用的路由导航。

本申请实施例所提供的页面导航方法,提供Flutter混合开发中常见三种业务场景的支持:

场景一,Native与Flutter全屏页面互相跳转,构成混合路由栈:

如图3所示,图3为本申请实施例中一种一个业务中Native页面打开全屏Flutter页面的场景示意图。即,点击Native原生页面中的观看记录按钮,即可打开一个Flutter观看记录列表页。

场景二,在Native页面中打开Flutter半屏(局部)页

如图4所示,图4为本申请实施例中一种是直播间业务中点击Native直播间中右上角图标来打开一个Flutter半屏页的示意图。

这里也存在一些扩展的使用场景,例如Tab模块某几个Tab页(即标签页)是Flutter,但Tabbar(标签栏)和剩余的Tab页是Native实现。

场景三,在同一个Native页面中同时持有两个或两个以上FlutterView,并支持携带局部视图的混合栈跳转:

如图5所示,图5为本申请实施例中一种在Native的直播间内,红包模块和挂件模块由两个FlutterView开发而成的示意图。即同一个Native的直播间内存在多个FlutterView。

Flutter混合栈方案有闲鱼的Flutter Boost与哈啰单车的Flutter Thrio框架。

Flutter Boost是闲鱼团队开源的Flutter混合框架,成熟稳定,业内影响力高,当Flutter跳转Flutter时,采用的是实例化一个新的FlutterViewController或FlutterActivity后使用原生导航栈跳转的方式,如下图6所示,这么做的好处是使用者(业务开发者)操作Flutter容器就如同操作WebView一样,而Flutter页面就如同Web页面,逻辑上简单清晰,将所有的导航路由逻辑收归到原生侧处理。

Flutter Thrio是一款混合栈框架。哈啰单车在早期也是使用Flutter Boost框架进行混合开发,但自觉Flutter Boost能力简单且其技术方案已经过时,于是自研了Flutter Thrio,核心是为了解决Flutter Boost的痛点问题并提供更加丰富的能力,具体包括:

尽可能复用Flutter容器,完美支持Navigator,减少内存占用;

支持多引擎;

框架提供更为完善的生命周期钩子与通知机制。

可以发现Flutter Thrio相较于Flutter Boost做出的最重要的改变在于Flutter跳转Flutter这种场景下,Thrio使用了Flutter Navigator导航栈,而不再实例化一个新Flutter容器,从而达到减少内存占用的目的。如图7所示。

Flutter Boost存在的问题如下:

Flutter引擎只能同时最多持有一个Flutter容器,因此在切换Flutter容器时必然会导致被切换的页面逻辑暂停,且App后台中Flutter逻辑无法执行。无法解决单页面内存在多个FlutterView的场景,即无法支持场景三。没有提供路由栈维护方案,只能使用系统提供的默认栈导航。

Flutter Thrio存在的问题如下:

Flutter跳转Flutter只能使用Navigator,不支持打开一个新的Flutter容器,导致跳转动画与原生路由不一致,会导致割裂感。支持多引擎,但是没有使用FlutterEngineGroup来维护管理多引擎,导致内存占用巨大。不支持Flutter Fragment。无法解决单页面内存在局部FlutterView的场景,即无法支持场景二。不支持FlutterFragment,所以无法支持场景三。

综上,以上两种方案仅仅提供了Flutter混合开发中的路由导航能力,在多引擎与局部视图上支持并不完备,没有提供健全的路由栈维护机制。而本申请所提供的页面导航方法,除了支持丰富的路由跳转能力之外,还区别于两者设计并提供了一套多Flutter局部视图下的混合路由跳转的栈维护方案,以解决以上两个框架各自的全部缺陷。

具体的,本申请所提供的页面导航方法,其核心能力在产品侧体现在两个方面:

一,框架层提供丰富的路由跳转能力:

该技术方案同时支持3种不同的混合跳转方式:

1、Flutter跳转Flutter时可以通过参数控制来使用新的容器来跳转,保证原生级体验。

2、Flutter跳转Flutter时可以通过参数控制来使用Flutter Navigator来跳转,保证状态持久性。

3、Native跳转Flutter或是Flutter跳转Flutter不仅仅支持单引擎内部的Flutter跳转切换,同时也支持多引擎实例之间的切换,以保证Flutter后台保活。(如下图8所示)

二、框架层支持多种Flutter嵌入能力:

该技术方案同时支持3种不同的Flutter嵌入能力:

1、Flutter作为全屏页嵌入到容器之中,这是Flutter混合开发中最常见的场景。

2、Flutter作为单个局部容器嵌入到原生页面之中,使用FlutterFragment(Android)和单引擎的FlutterView(iOS)进行封装来实现。

3、Flutter作为多个局部容器嵌入到原生页面之中。

下面以第6种能力的产品侧举例:

例1:多Flutter局部视图作为局部组件:

这是业务里最常见的场景(具体参见图5所示场景),前文已详述,此处不再赘述。

例2:多Flutter局部视图作为Tab页:

请参考图9属于例1的扩展应用,Flutter View作为多个Tab页来渲染。因为整个TabBar组件包括3个TabView原本都属于同一个原生容器,这里把Tab2和Tab3这两个Tab页作为拆出来作为Flutter View来渲染(而TabBar依然是Native的),这种场景也属于Flutter多局部视图能力。

然而这个案例Flutter Boost由于提供了FlutterViewController和FlutterFragment,因此使用Flutter Boost也可以实现。但是,Flutter Boost无法做到多Flutter Tab各自维持记录状态,比如第三个Tab滑到一半切到别的Tab再且回来,Tab3会重新渲染,无法记录状态。并且Tab间左右滑动时体验无法做到丝滑过度。这是因为FlutterBoost目前只能最多同时提供一个活跃的FlutterViewController,在实现多个Tab时只是不断设定哪个FlutterViewController处于活跃状态。此外,如果应用一启动便是一个Flutter Tab页,即FlutterView作为应用根页面,这种能力Flutter Boost和Thrio都不支持。即本申请支持FlutterView作为应用根页面,同时也支持多局部视图后台保活,以满足一些业务逻辑或体验需求。

例3:兼顾多局部视图的混合路由栈维护:

处理多Flutter Tab场景以外,还能兼顾存在多局部视图的路由栈维护,业务可以随时出入栈。

请参考图10,如点击Tab局部视图中的观看记录按钮,会跳到一个Flutter全屏页,继续点击观看记录页面中的头像又可以跳到一个Native页面;或者点击Tab局部视图中的我的心愿社按钮,可以跳到一个Web页,在Web页中点击某个按钮可以跳到一个Native页(此时已出栈),假设在那个Native页面中存在一个按钮点击之后又可以回到Flutter页面(此处又入栈)。即该发明支持多局部视图场景下的随时出入栈的混合路由栈维护能力。

下面从技术实现角度为例,对本申请所提供的页面导航方法进行详细说明:

为了方便介绍技术方案,先定义几个引擎:

1、main:框架提供的默认引擎,无需注册;

2、module1:框架额外注册的引擎;

3、module2:框架额外注册的引擎;

4、module3:框架额外注册的引擎;

此外,再约定几个页面:

1、home:Native根页面,不入栈;

1、route_pageA:Flutter页面,被main引擎注册,以外也被module2和module3引擎注册;

2、route_pageC:Flutter页面,被main引擎注册;

3、route_pageE:Flutter页面,被module1引擎注册,被module3引擎注册;

4、route_nativeA:Native页面;

5、route_nativeB:Native页面,里面包含2个Flutter局部视图:route_pageA(module2),route_pageE(module3)。

以上各页面内部都存在若干个按钮,可以让它们之间能够任意跳转。

可实现以下路由的场景:

1、home跳转route_pageA;

2、route_pageA使用新的Activity跳转route_pageC;

3、route_pageC使用Navigator跳转route_pageA;

4、route_pageA跳转route_nativeA;

最后,两端路由栈如图11所示。

需要注意的是,携带多局部视图的场景下,本方案依然支持Navigator与使用新的FlutterViewController打开页面,并且在push之后能依然保留前一个页面的状态。

最后举一个极端复杂的、携带局部视图的路由跳转场景,以此来说明本申请的多引擎路由栈的维护策略:

1、首先push Flutter页面route_pageA;

2、使用新的ViewController(容器)再打开Flutter页面route_pageC;

3、接着使用Navigator打开Flutter页面route_pageA;

4、之后打开一个native页面route_nativeA;

5、route_nativeA再打开一个新引擎module1上的Flutter页面route_pageE;

6、之后打开一个native页面route_nativeA;

7、之后再打开一个native页面route_nativeB,这个route_nativeB内部有两个Flutter局部视图,分别是module2的route_pageA和module3的route_pageE;

8、点击module3的route_pageE中的按钮,使用Navigator跳转至同引擎的route_pageA(因此这个route_pageA依然为局部视图,依据规则,不会入Native的路由栈上下文);

9、最后点击module3的route_pageA中的按钮跳转到module1的route_pageA。

最终框架路由栈上下文结构如图12a,图12b、图12c和图12d所示,其中图12b(对应图12a中的a)、图12c(对应图12a中的b)和图12d(对应图12a中的c),并共同构成一个完整路由栈。

可见,本申请所提供的页面导航方法,可以为业务提供智能的、多样的、全面的Flutter混合路由能力,可以满足业务侧实现多Flutter局部视图的业务场景,并且在多局部视图跳转时依然能随时出入栈、维护完整的路由信息、触发正确的事件钩子,供业务侧灵活使用。

相应于上面的方法实施例,本申请实施例还提供了一种页面导航装置,下文描述的页面导航装置与上文描述的页面导航方法可相互对应参照。

参见图13所示,该装置包括以下模块:

页面跳转需求信息获取模块101,用于接收并解析页面跳转请求,得到页面跳转需求信息;

调用方确定模块102,用于根据页面跳转需求信息,从路由栈框架的Flutter侧和Native侧中确定调用方;其中,Flutter侧和Native侧均暴露具有相同路由栈上下文数据结构的路由栈信息,且在路由栈框架中每个引擎维护各自引擎上的路由栈上下文,Native侧维护路由栈框架中全端的路由栈上下文;

路由参数确定模块103,用于从调用方对应的目标路由栈上下文中,查找与页面跳转需求信息对应的路由参数;

页面跳转导航模块104,用于利用路由参数,在路由栈框架中对应的Flutter侧和/或Native侧进行页面跳转导航。

应用本申请实施例所提供的装置,接收并解析页面跳转请求,得到页面跳转需求信息;根据页面跳转需求信息,从路由栈框架的Flutter侧和Native侧中确定调用方;其中,Flutter侧和Native侧均暴露具有相同路由栈上下文数据结构的路由栈信息,且在路由栈框架中每个引擎维护各自引擎上的路由栈上下文,Native侧维护路由栈框架中全端的路由栈上下文;从调用方对应的目标路由栈上下文中,查找与页面跳转需求信息对应的路由参数;利用路由参数,在路由栈框架中对应的Flutter侧和/或Native侧进行页面跳转导航。

在路由栈框架中Flutter侧和Native侧均暴露具有相同路由栈上下文数据结构的路由栈信息且有着对应的引擎进行维护。在有页面跳转导航需求时,便可基于相应的路由栈上下文实现智能的页面跳转导航。具体的,接收并解析页面跳转请求后,可以得到跳转需求信息。然后,基于跳转需求信息明确调用方,从该调用方对应的目标路由器栈上下文中查找出与该跳转需求信息匹配的路由参数。利用路由参数,在路由栈框架中对应的Flutter侧和/或Native侧,便可实现能够满足该页面跳转需求信息对应的页面跳转导航。可见,在本申请,基于目标路由栈上下文,不仅具有Flutter混合开发中的路由导航能力,还可在多引擎与局部视图上进行支持。

相应于上面的方法实施例,本申请实施例还提供了一种电子设备,下文描述的一种电子设备与上文描述的一种页面导航方法可相互对应参照。

参见图14所示,该电子设备包括:

存储器332,用于存储计算机程序;

处理器322,用于执行计算机程序时实现上述方法实施例的页面导航方法的步骤。

具体的,请参考图15,图15为本实施例提供的一种电子设备的具体结构示意图,该电子设备可因配置或性能不同而产生比较大的差异,可以包括一个或一个以上处理器(central processing units,CPU)322(例如,一个或一个以上处理器)和存储器332,存储器332存储有一个或一个以上的计算机应用程序342或数据344。其中,存储器332可以是短暂存储或持久存储。存储在存储器332的程序可以包括一个或一个以上模块(图示没标出),每个模块可以包括对数据处理设备中的一系列指令操作。更进一步地,中央处理器322可以设置为与存储器332通信,在电子设备301上执行存储器332中的一系列指令操作。

电子设备301还可以包括一个或一个以上电源326,一个或一个以上有线或无线网络接口350,一个或一个以上输入输出接口358,和/或,一个或一个以上操作系统341。

上文所描述的页面导航方法中的步骤可以由电子设备的结构实现。

相应于上面的方法实施例,本申请实施例还提供了一种可读存储介质,下文描述的一种可读存储介质与上文描述的一种页面导航方法可相互对应参照。

一种可读存储介质,可读存储介质上存储有计算机程序,计算机程序被处理器执行时实现上述方法实施例的页面导航方法的步骤。

该可读存储介质具体可以为U盘、移动硬盘、只读存储器(Read-Only Memory,ROM)、随机存取存储器(Random Access Memory,RAM)、磁碟或者光盘等各种可存储程序代码的可读存储介质。

本领域技术人员还可以进一步意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、计算机软件或者二者的结合来实现,为了清楚地说明硬件和软件的可互换性,在上述说明中已经按照功能一般性地描述了各示例的组成及步骤。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。本领域技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本申请的范围。

39页详细技术资料下载
上一篇:一种医用注射器针头装配设备
下一篇:多个子系统接入的接入开发方法、装置和系统、及介质

网友询问留言

已有0条留言

还没有人留言评论。精彩留言会获得点赞!

精彩留言,会给你点赞!