Android时间与服务器同步方案

news2024/12/26 11:25:52

转自:

https://blog.csdn.net/qinci/article/details/70666631这个的吧?转发请注明来源吧?Android时间与服务器同步方法_飛舞的青春的博客-CSDN博客Android时间与服务器同步方案 在部分软件应用场景里,我们对应用时间要求非常苛刻,如活动、商品秒杀倒计时操作,防止用户修改本机时间,导致应用错乱。 我们如果能让本地应用时间与服务器时间在误差应许范围内,保持同步,就能有效减少应用出错率。1. 预备SystemClock.elapsedRealtime() :手机系统开机时间(包含睡眠时间),用户无法在设置里面修改在必要的时刻获取https://blog.csdn.net/qinci/article/details/70666631

前言

在部分场景里,应用对时间的要求比较严苛,比如金融类app,股票类、期货等,对交易区间的判断是非常重要的。这就需要客户端的时间与服务器时间或者是世界标准时间同步,而不能简单地获取本地时间就可以了。

本方案思路

基于android系统提供的方法SystemClock.elapsedRealtime(),即手机系统开机时间。再配合服务器时间(或世界标准时间)实现移动端时间的准确性。

  1. SystemClock.elapsedRealtime() :手机系统开机时间(包含睡眠时间),用户无法修改
  2. 在必要的时刻获取一下服务器时间,然后记录这个时刻的手机开机时间(elapsedRealtime)
  3. 后续时间获取:现在服务器时间 = 以前服务器时间 - 以前服务器时间的获取时刻的手机开机时间 + 现在手机开机时间

移动端启动系统时间 = 以前服务器时间 - 以前服务器时间的获取时刻的手机开机时间

具体代码如下

/**
 * <pre>
 * author : Haitao
 * blog   : http://blog.nhtzj.com
 * time   : 2018/4/2
 * desc   : Android时间与服务器同步方案<br>
 *          1.SystemClock.elapsedRealtime() :手机系统开机时间(包含睡眠时间),用户无法在设置里面修改<br>
 *          2.在必要的时刻获取一下服务器时间,然后记录这个时刻的手机开机时间(elapsedRealtime)<br>
 *          3.后续时间获取:现在服务器时间 = 以前服务器时间 + 现在手机开机时间 - 以前服务器时间的获取时刻的手机开机时间<br>
 * version: 2.0
 * </pre>
 */
public class TimeManager {
    private static TimeManager instance;
    private long differenceTime;        //以前服务器时间 - 以前服务器时间的获取时刻的系统启动时间,即:手机开机时的服务器时间
    private boolean isServerTime;       //是否是服务器时间

    private TimeManager() {
    }

    public static TimeManager getInstance() {
        if (instance == null) {
            synchronized (AppManager.class) {
                if (instance == null) {
                    instance = new TimeManager();
                }
            }
        }
        return instance;
    }

    /**
     * 获取当前时间
     *
     * @return the time
     */
    public synchronized long getServiceTime() {
        if (!isServerTime) {
            //todo 这里可以加上触发获取服务器时间操作
            return System.currentTimeMillis();
        }

        //时间差加上当前手机启动时间就是准确的服务器时间了
        return differenceTime + SystemClock.elapsedRealtime();
    }

    /**
     * 时间校准
     *
     * @param lastServiceTime 当前服务器时间
     * @return the long
     */
    public synchronized long initServerTime(long lastServiceTime) {
        //记录时间差
        differenceTime = lastServiceTime - SystemClock.elapsedRealtime();
        isServerTime = true;
        return lastServiceTime;
    }
}

然后只要把软件调用System.currentTimeMillis()全部替换成TimeManager.getInstance().getServiceTime();即可获取到准确时间。

利用OkHttp的Interceptor自动同步时间

使用了Okhttp请求框架的,可以利用OkHttp的Interceptor自动同步时间

  1. 网络响应头包含Date字段(世界标准时间)。比如:Date: Mon, 02 Apr 2018 12:36:04 GMT,换算成本地时间,需要知道用户所在的时区
  2. 利用Interceptor记录每次请求响应时间,如果本次网络操作的时间小于上一次网络操作的时间,则获取Date字段,转换时区后更新本地TimeManager。
  3. 这样时间就只会越来越精确了

详细代码如下

/**
 * <pre>
 * author : Haitao
 * blog   : http://blog.nhtzj.com
 * time   : 2018/4/2
 * desc   : 利用OkHttp的Interceptor自动同步时间
 * version: 2.0
 * </pre>
 */
public class TimeCalibrationInterceptor implements Interceptor {
    long minResponseTime = Long.MAX_VALUE;

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        long startTime = System.nanoTime();
        Response response = chain.proceed(request);
        long responseTime = System.nanoTime() - startTime;

        Headers headers = response.headers();
        calibration(responseTime, headers);
        return response;
    }

    private void calibration(long responseTime, Headers headers) {
        if (headers == null) {
            return;
        }

        //如果这一次的请求响应时间小于上一次,则更新本地维护的时间
        if (responseTime >= minResponseTime) {
            return;
        }

        String standardTime = headers.get("Date");
        if (!TextUtils.isEmpty(standardTime)) {
            Date parse = HttpDate.parse(standardTime);
            if (parse != null) {
                // 客户端请求过程一般大于比收到响应时间耗时,所以没有简单的除2 加上去,而是直接用该时间
                TimeManager.getInstance().initServerTime(parse.getTime());
                minResponseTime = responseTime;
            }
        }
    }
}

之后将改Interceptor添加入OkHttpClient即可。

OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .connectTimeout(20000L, TimeUnit.MILLISECONDS)
                    .readTimeout(20000L, TimeUnit.MILLISECONDS)
                    .addInterceptor(new RetryIntercepter(2)) //出错重试
                    .addInterceptor(new LoggerInterceptor("TAG", true)) //Log 打印信息
                    .addInterceptor(new TimeCalibrationInterceptor()) //时间同步
                    .build()

OK,大功告成!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/160967.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mysql navicat函数_Navicat for MySQL函数高级属性

过程和函数是一组可以保存在服务器上的SQL语句。MySQL(www.formysql.com)函数高级属性主要涉及安全性&#xff0c;定义者&#xff0c;数据访问&#xff0c;决定性等方面的内容Navicat 函数高级属性安全性&#xff1a;指定用创建函数的用户权限来运行函数&#xff0c;或是用启用…

【C++】vector (vector的介绍及使用)

文章目录vector的介绍及使用前面我们学习了string&#xff0c;我们在学vector可以结合之前的理解&#xff0c;所以我们vector就不详细介绍了。 vector的介绍及使用 vector是表示可变大小数组的序列容器。就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就…

一个没有混进大厂的普通程序员,10年真实收入变化

有人说&#xff0c;程序员的高收入和工作年限成正比&#xff0c;认为自己的薪资应该如此计算&#xff1a; private static boolean 计算工资() { //years工作时长(年)int years 5;while(years-- > 0){做项目();团建活动();涨工资();拿年终奖();}return 跳槽() &&…

2021年亚太杯APMCM数学建模大赛A题图像边缘分析与应用求解全过程文档及程序

2021年亚太杯APMCM数学建模大赛 A题 图像边缘分析与应用 原题再现&#xff1a; 随着科学技术的发展&#xff0c;对各种工件和零部件测量精度的要求越来越高&#xff0c;对测量仪器的要求也越来越高。数字图像尺寸测量仪器等各种图像测量设备目前正逐渐取代传统的手动卡尺测量…

Vue 常用内置指令

Vue 常用内置指令描述指令内容渲染指令{{}} 与 v-text覆盖面积v-text{{}}闪现问题{{}}v-textv-html属性绑定指令v-bind简写 :事件绑定指令v-on参数事件对象$event事件修饰符按键修饰符双向绑定指令v-model修饰符条件渲染指令v-show 与 v-if 的区别实现原理性能消耗举个栗子v-el…

C#构建Web服务项目实战(二)

概述本文演示了如何通过Ajax访问C# ASP.NET项目中的WebService方法&#xff08;.asmx文件形式&#xff09;。本文的项目配置参见前文&#xff1a;C#构建Web服务项目实战&#xff08;一&#xff09;。环境Visual Studio 2017 / VS2019C# ASP.NET Web服务Win11 / Win10类似.NET F…

由浅入深地学习指针(学习指针必看)

目录 指针初阶 指针定义 指针和指针类型 c语言的整型指针解引用与整型变量的区别 内存 指针和指针类型 指针类型的意义 野指针 规避野指针 指针运算 指针和数组 二级指针 指针数组 指针进阶 指针的概念再提起 字符指针 《剑指offer》 字符串常量&#xff1a; …

【基于机械臂触觉伺服的物体操控研究】UR5e运动学建模及代码实现

我的毕设题目定为《基于机械臂触觉伺服的物体操控研究》&#xff0c;这个系列主要用于记录做毕设的过程。 前言&#xff1a;UR系列是优傲公司的代表产品&#xff0c;也是目前比较通用的产品级机械臂。所以我打算用该机械臂进行毕设的仿真实现。关于其运动学建模&#xff0c;网…

【每日一题】【LeetCode】【第十二天】区域和检索 - 数组不可变

解决之路 题目描述 测试案例&#xff08;部分&#xff09; 第一次 emmm&#xff0c;说实话&#xff0c;一开始我还真没看懂题目是什么意思。。。。 自己按我自己理解的方式写了一下代码&#xff0c;用测试案例跑了下&#xff0c;成功了。 不过&#xff0c;放进去跑不通&…

VScode远程调试深度学习debug

VS Code CtrlP&#xff0c;在搜索框>select interpreter检查一下python环境 #查看GPU 环境&#xff1b;版本号 nvidia-smi.exe使用VSCode进行深度学习首先进行debug 首先要安装Remote Development个人理解可以远程打开编辑文件。 点击左下角的箭头&#xff0c;在对话框中…

async-excel整合站内信通知用户体验感满满

前面的文章我们讲过消息中心站内信的实现 【消息中心】 那么本章我们来说说异步导入导出完成后&#xff0c;如何使用消息中心站内信的功能进行通知用户业务处理完成了 在async-excel中异步逻辑处理完成后会调用一个callback方法进行回调&#xff0c;所以我们可以再对async-exc…

完全二叉树与堆(包含STL堆的用法)

完全二叉树 完全二叉树为一类特殊的二叉树&#xff0c;高度为h的完全二叉树满足如下条件&#xff1a; &#xff08;1&#xff09;所有叶结点都出现在第h或h-1层&#xff1b; &#xff08;2&#xff09;第h-1层的所有叶结点都在非叶结点的右边&#xff1b; &#xff08;3&#…

AAAI 2023|模拟人脑场景感知过程,套娃Transformer讲故事能力更上一层楼

原文链接&#xff1a;https://www.techbeat.net/article-info?id4467 作者&#xff1a;seven_ 视频字幕生成目前已成为工业界AI创作领域非常火热的研究话题&#xff0c;这一技术可以应用在短视频的内容解析和讲解中&#xff0c;AI讲故事的技术已经越来越成熟。而在学术界&…

13、ThingsBoard-如何发送告警邮件

1、概述 很多时候,我们使用thingsboard的时候,会遇到比如一个设备触发了告警,如何将设备的告警消息定义成邮件模板,然后通知租户或者客户管理员,管理员进行处理,这样的需求是非常重要的。 2、实现的步骤 要实现这个需求我总结了几步: 2.1、设备上报的参数与阈值进行…

基于关键点检测的病患步态检测及分析方法

在临床工作中&#xff0c;对患有神经系统或骨骼肌肉系统疾病而可能影响行走能力的患者需要进行步态分析&#xff0c;以评定患者是否存在异常步态以及步态异常的性质和程度 步态评定临床意义 1、评估患者是否存在异常步态以及步态异常的性质和程度 2、为分析异常步态原因和矫正异…

看我们应用性能监控如何几秒钟定位慢访问跟因

背景 某汽车集团的汽车配件电子图册系统是其重要业务系统。最近业务部门反映&#xff0c;汽车配件电子图册调用图纸时&#xff0c;出现访问慢现象。 某汽车集团总部已部署NetInside流量分析系统&#xff0c;使用流量分析系统提供实时和历史原始流量。本次分析重点针对汽车配件…

二进制?十进制!

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 给定两个十进制整数 : AAA,BBB 你需要把它们的二进制形式以十进制的运算法则相加输出结果。 例如&#xff1a; A3,B2A 3 , B 2A3,B2 的时候&#xff0c;AAA 的二进制表示是 : 111111 , BB…

Linux部署Nexus通过Maven推送及拉取代码

&#x1f60a; 作者&#xff1a; 一恍过去&#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390&#x1f38a; 社区&#xff1a; Java技术栈交流&#x1f389; 主题&#xff1a; Linux部署Nexus通过Maven推送及拉取代码⏱️ 创作时间&#xff1a; 2023年…

myBaits Expert Wheat Exome — 从多个小麦品种中富集超过250Mb的高可信度的外显子

myBaits Expert Wheat Exome 与国际小麦基因组测序联盟(IWGSC)合作开发&#xff0c;使用了IWGSC发布的中国春基因组和注释信息。靶向六倍体小麦中完整的高置信度且有基因注释的外显子区域,能够全面、统一、可靠地深入覆盖大干15 Gb的小麦基因组中超过250 Mb的CDS及其邻近区域。…

硅烷聚乙二醇活性酯;Silane-PEG-NHS;溶于大部分有机溶剂。仅供科研实验使用,不用于诊治

英文名称&#xff1a;Silane-PEG-NHS&#xff0c;Silane-PEG-SCM 中文名称&#xff1a;硅烷聚乙二醇活性酯 分子量&#xff1a;1k&#xff0c;2k&#xff0c;3.4k&#xff0c;5k&#xff0c;10k&#xff0c;20k。。。 存储条件&#xff1a;-20C&#xff0c;避光&#xff0c;…