AiWork热更新在webui中的具体实现

前端UI部分

界面加载完成后,先初始化一个共享变量,防止数据污染

window.at.publicSet('update_info', false);   // 写入公共变量

let update_info;   // 更新信息

接下来执行异步更新

checkUpdate();   //检测并更新(异步方式)

/**
 * 检测并更新(异步方式)
 * @author 飞云
 * @wechat imfeiyun
 * @link  http://www.feiyunjs.com
 */
function checkUpdate() {
    $("#btn_begin").addClass('weui-btn_disabled').prop("disabled", true);   //禁用

    $.showLoading('更新中...');

    /////////////////////////////////////////////////////////////////////////////////////////////

    //////异步执行更新模块

    performAsyncTask();
    function asyncOperation() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                window.at.runJsFile('update.js');
                console.log('异步操作完成');
                resolve();
            }, 1000);
        });
    }

    async function performAsyncTask() {
        await asyncOperation();
        console.log('async/await 的代码继续执行');
    }

    /////////////////////////////////////////////////////////////////////////////////////////////

    // ///   限时检测是否更新完成
    let limitInMillis = 60 * 1000;   // 限制N秒

    // 调用递归函数,每隔 N 毫秒检查一次共享变量,总执行时间限制为 N 毫秒(exampleCondition返回true可提前结束循环)
    executeWithInterval(3 * 1000, limitInMillis, exampleCondition)
        .then((stoppedDueToCondition) => {
            // 判断返回值(存在返回值,说明递归循环结束)
            if (stoppedDueToCondition) {
                console.log('任务因条件满足而停止');
            } else {
                console.log('任务因时间限制到达而停止');
            }

            $.hideLoading();   // 更新完成(成功/失败),关闭loading

            // 判断消息类型,并弹出提示
            switch (update_info['tips_type']) {
                case 'toptip':
                    $.toptip(update_info['msg'], update_info['result'] ? 'success' : 'error');
                    break;
                case 'alert':
                    $.alert(update_info['msg']);
                    break;
                default:
                    break;
            }

            // 是否允许登录
            if (update_info['is_allow_login']) {
                $("#btn_begin").removeClass('weui-btn_disabled').prop("disabled", false);  // 解除禁用
            }

            // 设置设备信息
            let deviceInfo = update_info['device_info'];   // 字符串转对象
            let html = '';
            for (let key in deviceInfo) {
                html += '<tr><td>' + key + '</td><td>' + deviceInfo[key] + '</td></tr>';
            }
            $('#myTbody').append(html);   // 添加到表格中

        });
}

// 条件函数,返回 true 表示任务应该停止(停止递归)
function exampleCondition() {
    // 这里可以添加你的条件逻辑

    let info = window.at.publicGet('update_info');   // 读取公共变量
    update_info = JSON.parse(info);
    return toBooleanTrue(update_info['is_complete']);   // 返回 true 表示递归应该停止
}

/**
 * 在指定时间间隔内执行任务,直到达到总时间限制或某个条件满足为止,并返回是否因为条件满足而停止。
 * @param {number} intervalInMillis - 每次任务执行之间的时间间隔,单位为毫秒。
 * @param {number} durationInMillis - 总执行时间限制,单位为毫秒。
 * @param {function} condition - 判断是否停止执行任务的条件函数,返回 true 表示停止。
 * @returns {Promise<boolean>} - 一个 Promise 对象,解析为 true 表示因条件满足而停止,false 表示因时间限制到达而停止。
 * @author 飞云
 * @wechat imfeiyun
 * @link  http://www.feiyunjs.com
 */
function executeWithInterval(intervalInMillis, durationInMillis, condition) {
    return new Promise((resolve) => {
        const startTime = Date.now();
        const endTime = startTime + durationInMillis;

        function execute() {
            // 检查当前时间是否小于结束时间并且条件是否满足
            if (Date.now() < endTime && !condition()) {
                // 执行任务
                console.log('执行任务');

                // 设置延迟调用 execute 函数,以便在指定间隔后再次执行任务
                setTimeout(execute, intervalInMillis);
            } else {
                // 条件满足或总时间限制到达,停止执行
                const stoppedDueToCondition = condition(); // 检查条件是否满足
                console.log(stoppedDueToCondition ? '因条件满足而停止执行' : '时间限制到达,停止执行');
                resolve(stoppedDueToCondition); // 解析 Promise,返回 true 或 false
            }
        }

        // 启动任务执行
        execute();
    });
}

更新模块

为了方便管理,异步更新是在一个新的模块update.js中执行的。
在这个模块中,先从远程服务器获取应用信息。拿到信息以后,对比远程版本号和本地版本号。
不一致就下载热更新包。

异步请求的方法,详见:JavaScript异步处理一些事件:脚本的WEBUI开发中处理耗时操作

在执行异步操作的过程中,更新脚本需要和前端UI进行一些通信。
前端轮询更新的结果或者状态。

更新完成包含成功和失败。通常有以下几种结果:

  • 本地版本和远程版本一致,当前是最新版,无需更新
  • 版本不一致,下载热更新包成功,更新成功
  • 下载热更新包失败,更新失败
  • 获取更新信息失败,更新失败
  • 更新数据不合法,更新失败

为了方便通信,更新完成后,使用json格式的共享变量来传递信息。
参数名使用下划线命名。
例如:

publicData.set('update_info', JSON.stringify({
    result: true,
    msg: '更新成功,请重启应用',
    tips_type: 'alert',
    is_complete: true, // 是否完成更新
    is_allow_login: false, // 是否允许登录
    device_data: deviceData, // 设备信息
}));

参数说明:

  • result:更新结果,true/false
  • msg:消息提示文本内容
  • tips_type:消息提示类型,alert/toptip。前端根据这个值使用不同的消息提示组件显示消息内容
  • is_complete:是否完成更新,true/false。前端在一个限时的递归循环体中读取这个值,读取到true,说明更新结束,停止递归。
  • is_allow_login:更新完成后,是否允许用户点击登录按钮或者开始按钮。
  • device_data:将设备信息传递给前端,供前端渲染设备信息列表。

关联文章

AiWork开发WEBUI脚本界面中,使用异步方式检测更新的思路和具体实现
AiWork和autojs使用H5做脚本界面时,处理按钮的重复点击
AiWork和autojs可用的同步POST和异步POST请求,使用H5做脚本界面
autox.js结合JsBridge及weui+实现web界面的交互,应用WebView与 HTML开发脚本界面

1. 官方交流QQ群,添加多个不批。建议使用安卓手机或电脑申请。
飞云脚本圈: 586333520飞云脚本圈
Auto.js学习交流③群:286635606
Auto.js学习交流②群:712194666(满员)
IOS免越狱自动化测试群:691997586
2. 盗版,破解有损他人权益和违法作为,请各位会员支持正版。
3. 本站部分资源来源于用户上传和网络搜集,如有侵权请提供版权证明并联系站长删除。
4.如未特别申明,本站的技术性文章均为原创,未经授权,禁止转载/搬运等侵权行为。
5.全站所有付费服务均为虚拟商品,购买后自动发货。售出后概不接受任何理由的退、换。注册即为接受此条款。
6.如果站内内容侵犯了您的权益,请联系站长删除。
飞云脚本 » AiWork热更新在webui中的具体实现

企业级大数据智能营销管理系统

了解详情