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對象仍是要引發一些重視,方法不要亂用。。。

相關文章
相關標籤/搜索