uni-app Android平台5+ API提前生效 支持在plusready事件前调用

发布于 1周前 作者 gougou168 来自 Uni-App

uni-app Android平台5+ API提前生效 支持在plusready事件前调用

ios上plus是一直存在的,不涉及等ready事件。但安卓上还是需要等plus ready。

在安卓环境中,通常情况下需要html页面解析完成后才会让5+ API生效,安卓的执行的顺序为:

  1. 加载html页面,loading
  2. 解析html页面(解析title节点、下载script/link等节点引用的资源,如js/css文件)
  3. 触发DOMContentLoaded事件
  4. 触发plusready事件

此文对执行顺序有详细描述:http://ask.dcloud.net.cn/article/571

这样导致5+ API生效时间比较延后,通常采用以下代码等待plus ready后再调用5+ API:

document.addEventListener('plusready',function () {  
    // 在这里调用5+ API  
},false);

我们总是在不停追求性能优化,生效时间越早,我们可以把app的体验做的更好。

在HBuilder7.5版本之后安卓版支持提前注入5+ API,可以在plusready事件触发之前调用5+ API,操作方法是在页面中添加以下节点:

<!DOCTYPE html>  
<html>  
    <head>  
        <meta charset="utf-8"/>  
        <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"/>  
        <title>HTML5+ API</title>  
        <script src="html5plus://ready"></script>  
        <script type="text/javascript" charset="utf-8">  
// 这里可以调用5+ API了,为了更好的兼容性,应该使用以下代码进行判断  
if(window.plus){  
    // 在这里调用5+ API  
}else{// 兼容老版本的plusready事件  
    document.addEventListener('plusready',function () {  
        // 在这里调用5+ API  
    },false);  
}  
        </script>  
    </head>  
    <body>  
Hello HTML5 plus.  
    </body>  
</html>

注意

  1. 5+ API虽然可以提前生效,但为了不引发向下兼容问题,plusready事件并不会提前触发,该事件仍然保持原来的触发时机;
  2. 提前生效的Plus api,操作时需注意,此时DOMContentLoaded事件高概率未触发,此时操作dom会失败,操作dom也还是得等到DOMContentLoaded后;
  3. Android3.0及以上平台才支持提前生效,Android2.*版本不支持此功能;

应用场景举例

  • 定位 很多app的页面是根据位置来显示内容的,如果在DOMContentLoaded后再请求位置,然后再提交服务器获取该位置周边的商家列表,这样就会慢。而提前使用plus api获取位置,就可以加速页面显示速度。尤其对于首页就要拉周边信息的app更重要。

  • 父子页面加载 如果页面是父子webview布局,过去是父页面在触发plusready后再创建子页面,导致整体页面显出出来比较慢。如果让plus api提前生效,我们可以无需等待父页面plusready就直接创建子页面。


1 回复

在uni-app开发中,默认情况下,5+ API(即HTML5+扩展API)需要在plusready事件触发后才能安全调用,因为此时5+运行环境已经准备就绪。然而,在某些特殊场景下,我们可能希望在plusready事件之前就能调用5+ API。这通常需要对uni-app框架进行一些特殊处理或者利用一些技巧。

为了实现在plusready事件前调用5+ API,我们可以采用以下策略:

  1. 利用条件编译:在HBuilderX中,我们可以使用条件编译来区分不同的平台,从而在编译阶段就插入特定的代码逻辑。虽然这不能直接解决plusready前调用的问题,但可以帮助我们管理不同平台的代码差异。

  2. 自定义初始化逻辑:在App启动时,通过原生代码(如Android的Java或iOS的Objective-C/Swift)提前初始化需要的5+ API功能,然后在uni-app的JavaScript代码中通过某种机制(如全局变量或事件监听)来判断这些功能是否已经就绪。

不过,直接修改uni-app框架或HBuilderX的编译流程并不是推荐的做法,因为这可能会引入兼容性问题或难以维护的代码。下面是一个更实用的方法,利用一个封装好的JavaScript库来尝试在plusready前调用API(注意,这种方法并不保证在所有情况下都有效,因为它依赖于API的具体实现和uni-app框架的内部机制):

// 尝试在plusready前调用5+ API的封装函数
function tryCallPlusAPI(apiName, ...args) {
    if (window.plus && window.plus[apiName]) {
        return window.plus[apiName](...args);
    } else {
        // 如果plus未就绪,则使用setTimeout尝试延迟调用
        return new Promise((resolve, reject) => {
            const interval = setInterval(() => {
                if (window.plus && window.plus[apiName]) {
                    clearInterval(interval);
                    const result = window.plus[apiName](...args);
                    resolve(result);
                }
            }, 100); // 每100ms检查一次

            // 设置一个超时,防止无限等待
            setTimeout(() => {
                clearInterval(interval);
                reject(new Error('plus API not ready after timeout'));
            }, 5000); // 超时时间为5000ms
        });
    }
}

// 使用示例
tryCallPlusAPI('somePlusAPI', arg1, arg2)
    .then(result => {
        console.log('API call succeeded:', result);
    })
    .catch(error => {
        console.error('API call failed:', error);
    });

请注意,上述代码只是一个示例,实际使用中可能需要根据具体的5+ API和场景进行调整。同时,由于这种方法的可靠性取决于API的加载速度和系统的状态,因此不建议在关键路径上依赖这种方法。

回到顶部