react-native js引擎实现引起操做时间闪退

最近处理了RN一堆的闪退问题,心累,虽然创建了日志监控系统,并且借助了react16的错误边界Error Boundaries实现了兜底界面,可是仍是有直接闪退的状况react

问题现象

最近有测试指出安卓手机app上(为何老是安卓🤣)时间选择控件一划到2038年之后并读取值,app会直接闪退,通过原生同窗排除,表示不是安卓的问题,是RN的native js线程挂了,须要排查有问题的代码

排查问题时值得注意的是,debug远程开启后就没有问题,链接安卓真机就有问题,实际上是因为js引擎不一样形成的👇编程

JavaScript运行 时使用React Native时,您将在两个环境中运行JavaScript代码: 在iOS模拟器和设备上,Android模拟器和设备React Native使用JavaScriptCore,它是为Safari提供动力的JavaScript引擎。在iOS上,因为iOS应用程序中缺乏可写的可执行内存,所以JSC不使用JIT。 使用Chrome调试时,它会运行Chrome中的全部JavaScript代码,并经过WebSocket与本机代码进行通讯。因此你使用的是V8。浏览器

简单地说,安卓当前使用的是JSC引擎,实现细节,不经常使用的原生方法可能有所不一样。不过60版本之后可选用hermes赫尔墨斯bash

问题缘由

怀疑是 👉2038年问题app

在计算机应用上,2038年问题可能会致使某些软件在2038年没法正常工做。全部使用POSIX时间表示时间的程序都将受其影响,由于它们的时间起点是格林尼治时间1970年1月1日0时0分0秒(这个时间名叫 the Unix Epoch),它们用the Unix Epoch通过的秒数(忽略闰秒)来表示时间。这种时间表示法在类Unix(Unix-like)操做系统上是一个标准,并会影响以其C编程语言开发给其余大部份操做系统使用的软件。在大部分的32位操做系统上,此“time_t”数据模式使用一个有符号32位整数(signed int32)存储计算的秒数。依照此“time_t”标准,在此格式能被表示的最后时间是第2147483647秒(表明格林尼治时间2038年1月19日凌晨03:14:07)。下一秒,即格林尼治时间2038年1月19日凌晨03:14:08,因为32位整型溢出,时间将会被“绕回”(wrap around)成一个负数,变成了第 -2147483648 秒(表明格林尼治时间1901年12月13日20:45:52),形成应用程序发生严重的时间错误,而没法运行。框架

原生与RN通讯也会依赖C++代码写的桥接,RN的js引擎也是多半用C实现的,js某行代码有问题就会致使js线程挂掉,应用闪退编程语言

定位代码

通过古老可是有效的二分法查找代码方式😂,找到了有问题的代码测试

(new Date(2544695704409)).toLocaleDateString()
"2050/8/21"
// 修改后
moment(new Date(2544695704409)).format('L');
复制代码

在安卓机上,Date对象原型上挂载的toLocaleDateString方法一过2038年就挂掉了,说明如今跨端的框架仍是不够成熟,哪怕RN已经几年了,兼容性问题仍是有一些。spa

总结

使用日期对象的时候,直接使用moment.js等成熟的库,尽可能不要图省事用原生可是危险的方法。操作系统

  • toLocaleDateString方法在浏览器中实现也各不相同,主流的是返回结果"2050/8/21",可是某些版本的浏览器返回结果是"2050-8-21"
  • QQ浏览器低版本未正确实现 Date.prototype.toString()、Date.prototype.getDay()、Date.prototype.getTimezoneOffset()、new Date(Time String)等方法,时区没有按照当地时区取。

因此对于date对象仍是要引发一些重视,方法不要乱用。。。

相关文章
相关标签/搜索