JSAPI

  • 生命周期及窗口控制

    概念描述

    在Nebula容器中开发H5App,首先必须要理解H5App的生命周期和窗口控制的基本概念。
    为了方便理解,在这里我们可以用PC端的chrome浏览器来做概念参考。

    appId

    支付宝客户端内的应用id,用于让框架知晓需要启动哪个H5App,并且加载这个H5App默认的启动参数和离线包。

    启动参数

    当H5App启动时或者运行时,可以通过配置一些参数来控制某些特性,比如返回按钮的默认行为、导航栏的默认背景、是否开启下拉刷新,这些配置即为启动参数。

    H5App

    顾名思义为一个应用级的概念,可以理解为chrome浏览器中的一个独立进程,每启动一个H5App相当于全新创建了一个浏览器进程。

    Window

    可以理解chrome浏览器中的标签页的概念,一个H5App中可以包含一个或者多个window,这几个window可以共享一个app session(应用生命周期)

    undefined

    H5App生命周期

    启动H5App的两种方式

    通过scheme启动

    scheme可以理解为一种特殊的URI,格式与URI相同
    支付宝客户端的标准scheme为:alipays://platformapi/startapp?appId=

    即为H5App自身的appId,但如果是某些运营页之类的单独页面,没有自己的appId,可以使用Nebula容器的通用浏览器模式appId=20000067 来启动,同时将需要打开的H5页面url经过encode编码后设置到url参数内,例如:alipays://platformapi/startapp?appId=20000067&url=http%3A%2F%2Fm.taobao.com

    在scheme中配置的启动参数需要与appId同级,如果启动参数的值包含特殊字符,必须注意需要经过encode后再传递。

    通过JSAPI: startApp接口启动

    通过JSAPI: startApp接口,也可以启动一个H5App, 它相对于scheme的优势在于它可以在启动新的H5App时,可通过closeCurrentApp入参来同时关闭自身,用于某些特定的业务场景。

    退出H5App

    退出H5App也存在两种情况:
    第一种为当前H5App的窗口栈中的最后一个窗口也被销毁时,Nebula容器会同时自动销毁掉这个H5App实例
    第二种即为调用JSAPI: exitApp接口,可以在当前H5App下的任意一个window窗口中调用,关闭一整个当前H5App

    页面跳转及窗口控制

    H5在Nebula容器中有多种页面跳转的方式,除了原生的location.href / location.replace 之类的页面跳转方法以外,还有一个JSAPI: pushWindow接口

    location.href 和 location.replace 页面跳转

    location.href 和 location.replace的跳转,都是在当前窗口上做页面跳转,可以理解为chrome浏览器上在当前标签页做跳转而不是新开标签页。但是这两者在Nebula容器内有一定区别,主要是由于history.length的变化导致导航栏左上角返回按钮的行为和关闭按钮的显示逻辑上。

    当配置启动参数backBehavior为back时,点击返回按钮会先判断history.length,如果值为0,那么就会自动退出当前窗口,效果等同JSAPI: popWindow。 但如果history.length大于0,那么就会先执行history.back(),返回当前窗口的历史记录上一页,同时在导航栏返回按钮的右侧显示出一个『关闭』按钮。
    当配置启动参数backBehavior为pop时,点击返回按钮会直接退出当前窗口,效果等同JSAPI: popWindow。
    需要注意的是,如果当时的appId为通用浏览器模式的20000067,那么backBehavior的默认值为back,其它拥有自身appId的H5App默认值均为pop。

    JSAPI: pushWindow 打开新窗口

    JSAPI: pushWindow 含义为新开一个窗口后再打开指定H5页面,可以理解为chrome浏览器中的新开标签页。
    新开的窗口,导航栏、背景色等等Nebula容器特性都会独立于之前的窗口,因此可以通过pushWindow接口的param参数来单独设置每一个新开窗口的启动参数而不会影响到之前打开的老窗口。这对于某些业务在第一页需要透明导航栏但是后续页面不需要透明之类的场景尤为有用。

    pushWindow接口带有一个特殊的入参为closeCurrentWindow,含义为在打开新窗口后自动关闭当前窗口,效果类似于页面跳转的location.replace

    popWindow与popTo 关闭窗口

    popWindow与popTo均用于关闭窗口,区别在于popWindow仅会关闭当前窗口,而popTo可以同时关闭多个,效果类似于页面跳转的history.back(),而且由于历史窗口只是被压到栈底而并没有被销毁,因此历史窗口被重新显示后并不会触发页面刷新。

    另外如果当前是本应用的唯一窗口栈时,只能使用popWindow来退出这个最后的窗口而不能使用popTo

    pause与resume 窗口可见状态事件

    pause事件在当前窗口不可见的情况下会触发,包含窗口被压到栈底、或整个客户端被压到后台、或屏幕在当前窗口显示时被锁屏。
    resume事件与pause事件相对,当窗口重新变为可见时,将会触发,包括作为历史窗口被重新显示、或客户端从后台被唤起、或屏幕被解锁。

    从10.0.15客户端开始,容器新增了pagePause/pageResume和appPause/appResume事件,用于业务区分是哪种情况触发的pause/resume。
    pause = appPause(客户端被压后台、屏幕被锁屏) + pagePause(窗口被压栈底不可见)
    resume = appResume(客户端从后台被唤起、锁屏界面恢复) + pageResume(窗口从下个页面回退后恢复显示)

    跨应用跳转特殊场景

    在正常场景下,相同appId的H5App只能存在一个实例。因此当App1_page1唤起了App2_page1时,如果App2_page1希望再跳转到App1_page2时,默认情况下会先将App1_page1唤起到前台后销毁然后再显示App1_page2页面,此时的动画效果就会显得非常突兀。(A1–>B1–>A2)

    如果要解决这个问题,一般来说只需要在App2_page1唤起App1_page2时,携带上启动参数startMultApp=YES即可。 它的含义为允许重新创建一个App1的实例,代表了相同appId可以同时存在多个实例,但是带来相应的隐患为它们虽然是相同的appId,但应用实例(可以理解为一个独立的浏览器进程)并不是同一个,应用生命周期也各不相同,如果有某些依赖应用生命周期的功能就会受到影响,比如sessionData之类在相同应用生命周期内共享数据的接口。