整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Java 關鍵字之 native 詳解

          Java 關鍵字之 native 詳解

          篇博客我們將介紹Java中的一個關鍵字——native。

          native 關鍵字在 JDK 源碼中很多類中都有,在 Object.java類中,其 getClass() 方法、hashCode()方法、clone() 方法等等都是用 native 關鍵字修飾的。

          那么為什么要用 native 來修飾方法,這樣做有什么用?

          1、JNI:Java Native Interface

          在介紹 native 之前,我們先了解什么是 JNI。

          一般情況下,我們完全可以使用 Java 語言編寫程序,但某些情況下,Java 可能會不滿足應用程序的需求,或者是不能更好的滿足需求,比如:

          • ①、標準的 Java 類庫不支持應用程序平臺所需的平臺相關功能。
          • ②、我們已經用另一種語言編寫了一個類庫,如何用Java代碼調用?
          • ③、某些運行次數特別多的方法代碼,為了加快性能,我們需要用更接近硬件的語言(比如匯編)編寫。

          上面這三種需求,其實說到底就是如何用 Java 代碼調用不同語言編寫的代碼。那么 JNI 應運而生了。

          從Java 1.1開始,Java Native Interface (JNI)標準就成為java平臺的一部分,它允許Java代碼和其他語言寫的代碼進行交互。JNI一開始是為了本地已編譯語言,尤其是C和C++而設計 的,但是它并不妨礙你使用其他語言,只要調用約定受支持就可以了。使用java與本地已編譯的代碼交互,通常會喪失平臺可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的,比如,使用一些舊的庫,與硬件、操作系統進行交互,或者為了提高程序的性能。JNI標準至少保證本地代碼能工作在任何Java 虛擬機實現下。  

          通過 JNI,我們就可以通過 Java 程序(代碼)調用到操作系統相關的技術實現的庫函數,從而與其他技術和系統交互,使用其他技術實現的系統的功能;同時其他技術和系統也可以通過 JNI 提供的相應原生接口開調用 Java 應用系統內部實現的功能。

          在windows系統上,一般可執行的應用程序都是基于 native 的PE結構,windows上的 JVM也是基于native結構實現的。Java應用體系都是構建于 JVM 之上。  

          可能有人會問,Java不是跨平臺的嗎?如果用 JNI,那么程序不就將失去跨平臺的優點?確實是這樣的。

          JNI 的缺點:

          ①、程序不再跨平臺。要想跨平臺,必須在不同的系統環境下重新編譯本地語言部分。

          ②、程序不再是絕對安全的,本地代碼的不當使用可能導致整個程序崩潰。一個通用規則是,你應該讓本地方法集中在少數幾個類當中。這樣就降低了JAVA和C之間的耦合性。

          目前來講使用 JNI 的缺點相對于優點還是可以接受的,可能后面隨著 Java 的技術發展,我們不在需要 JNI,但是目前 JDK 還是一直提供對 JNI 標準的支持。

          2、用C語言編寫程序本地方法

          上面講解了什么是 JNI,那么我們接下來就寫個例子,如何用 Java 代碼調用本地的 C 程序。

          步驟如下:

          ①、編寫帶有 native 聲明的方法的java類,生成.java文件;(注意這里出現了 native 聲明的方法關鍵字)

          ②、使用 javac 命令編譯所編寫的java類,生成.class文件;

          ③、使用 javah -jni java類名 生成擴展名為 h 的頭文件,也即生成.h文件;

          ④、使用C/C++(或者其他編程想語言)實現本地方法,創建.h文件的實現,也就是創建.cpp文件實現.h文件中的方法;

          ⑤、將C/C++編寫的文件生成動態連接庫,生成dll文件;

          下面我們通過一個 HelloWorld 程序的調用來完成這幾個步驟。

          注意:下面所有操作都是在所有操作都是在目錄:D:\JNI 下進行的。

          一、編寫帶有native聲明的方法的java類

          用 native 聲明的方法表示告知 JVM 調用,該方法在外部定義,也就是我們會用 C 語言去實現。

          System.loadLibrary("helloJNI");加載動態庫,參數 helloJNI 是動態庫的名字。我們可以這樣理解:程序中的方法helloJNI() 在程序中沒有實現,但是我們下面要調用這個方法,怎么辦呢?我們就需要對這個方法進行初始化,所以用 static 代碼塊進行初始化。

          這時候如果我們直接運行該程序,會報“A Java Exception has occurred”錯誤:  


          二、使用javac命令編譯所編寫的java類,生成.class文件

          執行上述命令后,生成 HelloJNI.class 文件:

          三、使用javah -jni java類名生成擴展名為 h 的頭文件

          執行上述命令后,在 D:/JNI 目錄下多出了個 HelloJNI.h 文件:


          四、使用C語言實現本地方法

          如果不想安裝visual studio的,我們需要在 windows平臺安裝 gcc。

          注意安裝版本的選擇,根據系統是32位還是64位來選擇。

          安裝完成之后注意配置環境變量,在 cmd 中輸入 g++ -v,如果出現如下信息,則安裝配置完成:  

          接著輸入如下命令:

          -m64表示生成dll庫是64位的。后面的路徑表示本機安裝的JDK路徑。生成之后多了一個helloJNI.dll 文件

          最后運行 HelloJNI:輸出 Hello JNI! 大功告成。  

          3、JNI調用C的流程圖

          4、native關鍵字

          通過上面介紹了那么多JNI的知識,終于到介紹本篇文章的主角——native 關鍵字了。相信大家看完上面的介紹,應該也是知道什么是 native 了吧。

          native 用來修飾方法,用 native 聲明的方法表示告知 JVM 調用,該方法在外部定義,我們可以用任何語言去實現它。簡單地講,一個native Method就是一個 Java 調用非 Java 代碼的接口。

          native 語法:

          ①、修飾方法的位置必須在返回類型之前,和其余的方法控制符前后關系不受限制。

          ②、不能用 abstract 修飾,也沒有方法體,也沒有左右大括號。

          ③、返回值可以是任意類型

          我們在日常編程中看到native修飾的方法,只需要知道這個方法的作用是什么,至于別的就不用管了,操作系統會給我們實現。

          如若轉載,請注明出處:開源字節 https://sourcebyte.vip/article/385.html

          者|Lukas Gisder-Dubé

          譯者|謝麗

          本文將分三部分分析 JavaScript 中的錯誤,首先我們將了解錯誤的一般情況,之后,我們將關注后端(Node.js + Express.js),最后,我們將重點看下如何處理 React.js 中的錯誤。選擇這些框架,是因為它們是目前最流行的,但是,你應該也能夠將這些新發現應用到其他框架中吧!

          繼上一篇文章 (https://link.medium.com/MO32x55aNR) 之后,我想談談錯誤。錯誤很好——我相信你以前聽過這個說法。乍一看,我們害怕錯誤,因為錯誤往往會涉及到在公共場合受到傷害或羞辱。通過犯錯誤,我們實際上學會了如何不去做某事,以及下次如何做得更好。

          顯然,這是關于從現實生活的錯誤中學習。編程中的錯誤有點不同。它們為我們提供了很好的特征來改進我們的代碼,并告訴用戶什么地方出了問題(也可能是教他們如何修復它)。

          GitHub(https://github.com/gisderdube/graceful-error-handling) 上提供了一個完整的樣例項目。

          JavaScript 錯誤和一般處理

          throw new Error('something went wrong')?會在 JavaScript 中創建一個錯誤實例,并停止腳本的執行,除非你對錯誤做了一些處理。當你作為 JavaScript 開發者開啟自己的職業生涯時,你自己很可能不會這樣做,但是,你已經從其他庫(或運行時)那里看到了,例如,類似“ReferenceError: fs 未定義”這樣的錯誤。

          Error 對象

          Error 對象有兩個內置屬性供我們使用。第一個是消息,作為參數傳遞給 Error 構造函數,例如 new Error(“這是錯誤消息”)。你可以通過 message 屬性訪問消息:

          const myError=new Error(‘請改進代碼’)
          console.log(myError.message) // 請改進代碼
          

          第二個是錯誤堆棧跟蹤,這個屬性非常重要。你可以通過 stack 屬性訪問它。錯誤堆棧將為你提供歷史記錄(調用堆棧),從中可以查看哪個文件導致了錯誤。堆棧的上部也包括消息,然后是實際的堆棧,從距離錯誤發生最近的點開始,一直到最外層“需要為錯誤負責”的文件:

          Error: 請改進代碼
           at Object.<anonymous> (/Users/gisderdube/Documents/_projects/hacking.nosync/error-handling/src/general.js:1:79)
           at Module._compile (internal/modules/cjs/loader.js:689:30)
           at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
           at Module.load (internal/modules/cjs/loader.js:599:32)
           at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
           at Function.Module._load (internal/modules/cjs/loader.js:530:3)
           at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
           at startup (internal/bootstrap/node.js:266:19)
           at bootstrapNodeJSCore (internal/bootstrap/node.js:596:3)
          

          拋出和處理錯誤

          現在,Error 實例本身不會導致任何結果,例如,new Error('...') 不會做任何事情。當錯誤被拋出時,就會變得更有趣。然后,如前所述,腳本將停止執行,除非你在流程中以某種方式對它進行了處理。記住,是手動拋出錯誤,還是由庫拋出錯誤,甚至由運行時本身(Node 或瀏覽器),都沒有關系。讓我們看看如何在不同的場景中處理這些錯誤。

          try .... catch

          這是最簡單但經常被遺忘的錯誤處理方法——多虧 async / await,它的使用現在又多了起來。它可以用來捕獲任何類型的同步錯誤,例如,如果我們不把 console.log(b) 放在一個 try … catch 塊中,腳本會停止執行。

          … finally

          有時候,不管是否有錯誤,代碼都需要執行。你可以使用第三個可選塊 finally。通常,這與在 try…catch 語句后面加一行代碼是一樣的,但它有時很有用。

          異步性——回調

          異步性,這是在使用 JavaScript 時必須考慮的一個主題。當你有一個異步函數,并且該函數內部發生錯誤時,你的腳本將繼續執行,因此,不會立即出現任何錯誤。當使用回調函數處理異步函數時(不推薦),你通常會在回調函數中收到兩個參數,如下所示:

          如果有錯誤,err 參數就等同于那個錯誤。如果沒有,參數將是 undefined 或 null。要么在 if(err) 塊中返回某項內容,要么將其他指令封裝在 else 塊中,這一點很重要,否則你可能會得到另一個錯誤,例如,result 可能未定義,而你試圖訪問 result.data,類似這樣的情況。

          異步性——Promises

          處理異步性的更好方法是使用 Promises。在這一點上,除了代碼可讀性更強之外,我們還改進了錯誤處理。只要有一個 catch 塊,我們就不再需要太關注具體的錯誤捕獲。在鏈接 Promises 時,catch 塊捕獲會自 Promises 執行或上一個 catch 塊以來的所有錯誤。注意,沒有 catch 塊的 Promises 不會終止腳本,但會給你一條可讀性較差的消息,比如:

          (node:7741) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: something went wrong
          (node:7741) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. */
          

          因此,務必要在 Promises 中加入 catch 塊。

          回到 try … catch

          隨著 JavaScript 引入 async / await,我們回到了最初的錯誤處理方法,借助 try … catch … finally,錯誤處理變得非常簡單。

          因為這和我們處理“普通”同步錯誤的方法是一樣的,所以如果需要的話,更容易使用作用域更大的 catch 語句。

          服務器端錯誤的產生和處理

          現在,我們已經有了處理錯誤的工具,讓我們看下,我們在實際情況下能用它們做什么。后端錯誤的產生和處理是應用程序至關重要的組成部分。對于錯誤處理,有不同的方法。我將向你展示一個自定義 Error 構造函數和錯誤代碼的方法,我們可以輕松地傳遞到前端或任何 API 消費者。構建后端的細節并不重要,基本思路不變。

          我們將使用 Express.js 作為路由框架。讓我們考慮下最有效的錯誤處理結構。我們希望:

          1. 一般錯誤處理,如某種回退,基本上只是說:“有錯誤,請再試一次或聯系我們”。這并不是特別聰明,但至少通知用戶,有地方錯了——而不是無限加載或進行類似地處理。
          2. 特殊錯誤處理為用戶提供詳細信息,讓用戶了解有什么問題以及如何解決它,例如,有信息丟失,數據庫中的條目已經存在等等。


          構建一個自定義 Error 構造函數

          我們將使用已有的 Error 構造函數并擴展它。繼承在 JavaScript 中是一件危險的事情,但根據我的經驗,在這種情況下,它非常有用。我們為什么需要它?我們仍然希望堆棧跟蹤給我們一個很好的調試體驗。擴展 JavaScript 原生 Error 構造函數可以讓我們方便地獲得堆棧跟蹤。我們唯一要做的是添加代碼(我們稍后可以通過錯誤代碼訪問)和要傳遞給前端的狀態(http 狀態代碼)。

          如何處理路由

          在完成 Error 的自定義之后,我們需要設置路由結構。正如我指出的那樣,我們想要一個單點真錯誤處理,就是說,對于每一個路由,我們要有相同的錯誤處理行為。在默認情況下,由于路由都是封裝的,所以 Express 并不真正支持那種方式。

          為了解決這個問題,我們可以實現一個路由處理程序,并把實際的路由邏輯定義為普通的函數。這樣,如果路由功能(或任何內部函數)拋出一個錯誤,它將返回到路由處理程序,然后可以傳給前端。當后端發生錯誤時,我們可以用以下格式傳遞一個響應給前端——比如一個 JSON API:

          {
           error: 'SOME_ERROR_CODE',
           description: 'Something bad happened. Please try again or contact support.'
          }
          

          準備好不知所措。當我說下面的話時,我的學生總是生我的氣:

          如果你咋看之下并不是什么都懂,那沒問題。只要使用一段時間,你就會發現為什么要那樣。

          順便說一下,這可以稱為自上而下的學習,我非常喜歡。

          路由處理程序就是這個樣子:

          我希望你能讀下代碼中的注釋,我認為那比我在這里解釋更有意義。現在,讓我們看下實際的路由文件是什么樣子:

          在這些例子中,我沒有做任何有實際要求的事情,我只是假設不同的錯誤場景。例如,GET /city 在第 3 行結束,POST /city 在第 8 號結束等等。這也適用于查詢參數,例如,GET /city?startsWith=R。本質上,你會有一個未處理的錯誤,前端會收到:

          {
           error: 'GENERIC',
           description: 'Something went wrong. Please try again or contact support.'
          }
          

          或者你將手動拋出 CustomError,例如:

          throw new CustomError('MY_CODE', 400, 'Error description')
          

          上述代碼會轉換成:

          {
           error: 'MY_CODE',
           description: 'Error description'
          }
          

          既然我們有了這個漂亮的后端設置,我們就不會再把錯誤日志泄漏到前端,而總是返回有用的信息,說明出現了什么問題。

          確保你已經在 GitHub(https://github.com/gisderdube/graceful-error-handling) 上看過完整的庫。你可以把它用在任何項目中,并根據自己的需要來修改它!

          向用戶顯示錯誤

          下一個也是最后一個步驟是管理前端的錯誤。這里,你要使用第一部分描述的工具處理由前端邏輯產生的錯誤。不過,后端的錯誤也要顯示。首先,讓我們看看如何顯示錯誤。如前所述,我們將使用 React 進行演練。

          把錯誤保存在 React 狀態中

          和其他數據一樣,錯誤和錯誤消息會變化,因此,你想把它們放在組件狀態中。在默認情況下,你想要在加載時重置錯誤,以便用戶第一次看到頁面時,不會看到錯誤。

          接下來我們必須澄清的是不同錯誤類型及與其匹配的可視化表示。就像在后端一樣,有 3 種類型:

          1. 全局錯誤,例如,其中一個常見的錯誤是來自后端,或者用戶沒有登錄等。
          2. 來自后端的具體錯誤,例如,用戶向后端發送登錄憑證。后端答復密碼不匹配。前端無法進行此項驗證,所以這樣的信息只能來自后端。
          3. 由前端導致的具體錯誤,例如,電子郵件輸入驗證失敗。

          2 和 3 非常類似,雖然源頭不一樣,但如果你愿意,就可以在同樣的 state 中處理。我們將從代碼中看下如何實現。

          我將使用 React 的原生 state 實現,但是,你還可以使用類似 MobX 或 Redux 這樣的狀態管理系統。

          全局錯誤

          通常,我將把這些錯誤保存在最外層的有狀態組件中,并渲染一個靜態 UI 元素,這可能是屏幕頂部的一個紅色橫幅、模態或其他什么東西,設計實現由你決定。

          讓我們看下代碼:

          正如你看到的那樣,Application.js 中的狀態存在錯誤。我們也有方法可以重置并改變錯誤的值。我們把值和重置方法傳遞給 GlobalError 組件,在點擊'x'時,該組件會顯示錯誤并重置它。讓我們看看 GlobalError 組件:

          你可以看到,在第 5 行,如果沒有錯誤,我們就不做任何渲染。這可以防止我們的頁面上出現一個空的紅框。當然,你可以改變這個組件的外觀和行為。例如,你可以將“x”替換為 Timeout,幾秒鐘后重置錯誤狀態。

          現在,你已經準備好在任何地方使用全局錯誤狀態了,只是從 Application.js 把 _setError 向下傳遞,而且,你可以設置全局錯誤,例如,當一個請求從后端返回了字段 error: 'GENERIC'。例如:

          如果你比較懶,到這里就可以結束了。即使你有具體的錯誤,你總是可以改變全局錯誤狀態,并把錯誤提示框顯示在頁面頂部。不過,我將向你展示如何處理和顯示具體的錯誤。為什么?首先,這是關于錯誤處理的權威指南,所以我不能停在這里。其次,如果你只是把所有的錯誤都作為全局錯誤來顯示,那么體驗人員會瘋掉。

          處理具體的請求錯誤

          和全局錯誤類似,我們也有位于其他組件內部的局部錯誤狀態,過程相同:

          有件事要記住,清除錯誤通常有一個不同的觸發器。用' x '刪除錯誤是沒有意義的。關于這一點,在發出新請求時清除錯誤會更有意義。你還可以在用戶進行更改時清除錯誤,例如當修改輸入值時。

          源于前端的錯誤

          如前所述,這些錯誤可以使用與處理后端具體錯誤相同的方式(狀態)進行處理。這次,我們將使用一個有輸入字段的示例,只允許用戶在實際提供以下輸入時刪除一個城市:

          使用錯誤代碼實現錯誤國際化

          也許你一直想知道為什么我們有這些錯誤代碼,例如 GENERIC ,我們只是顯示從后端傳遞過來的錯誤描述。現在,隨著你的應用越來越大,你就會希望征服新的市場,并在某個時候面臨多種語言支持的問題。如果你到了這個時候,你就可以使用前面提到的錯誤代碼使用用戶的語言來顯示恰當的描述。

          我希望你對如何處理錯誤有了一些了解。忘掉 console.error(err),它現在已經是過去時了。可以使用它進行調試,但它不應該出現在最終的產品構建中。為了防止這種情況,我建議你使用日志庫,我過去一直使用 loglevel,我對它非常滿意。

          英文原文

          https://levelup.gitconnected.com/the-definite-guide-to-handling-errors-gracefully-in-javascript-58424d9c60e6

          者 | 魔笛

          責編 | 郭芮

          2015年3月,Facebook正式發布react-native,只支持iOS平臺;2015年9月,Facebook發布了React Native for Android,讓這一技術正式成為跨平臺開發框架。

          我們團隊是在2016年中期開始接觸并使用react-native, 起初團隊有很多反對聲,其中:

          • iOS平臺嚴格的審核制度,還有后來的JSPatch風波,擔心有熱更新的能力的react-native也會被禁用,還好react-native是以js.bundle為資源加載的沙盒熱更新;
          • React Native的性能能達到上限問題。

          當時選擇react-native的幾個重要因素:

          • 跨平臺:這可能是最重要的原因了,可以節省人力;
          • 基于React框架開發,組建化,響應式思路,調試方式可以縮短開發周期(在開發者熟練使用的情況下),也可以調整前端開發資源;
          • 熱更新:APP當時修復BUG基本都是重新發版,周期比較長,熱更新是解決這一個痛點是最好的選擇;
          • 新技術調研,擴展技術棧。

          移動框架學習套路

          每次接觸一個新技術、新框架我們總是一頭霧水。其實是有套路的,有經驗的程序員會說這就是思想,下面主要從移動開發這幾個方面調研:

          計算機語言工具

          環境搭建

          UI繪制

          基本布局方式

          基本tab + navigator的APP框架搭建

          網絡請求(http, https, 上傳,下載等)

          緩存, 本地存儲

          圖片

          平臺特性處理:例如推送,支付等等iOS,安卓不同的平臺代碼如何處理

          調試工具:好的調試工具不但可以事半功倍,還可以給開發者愉悅的心情開發

          靜態代碼檢查(這個對于解釋型的JS語言很重要)

          Unit Test

          CI集成方式

          以上幾個方面都研究明白了,整個react-native生產鏈路就調研完成了。

          技術棧

          針對上面的過程總結一下技術棧。

          需要的語言&框架

          • JavaScript - ECMAScript6:React Native是以JavaScript作為語言工具開發;
          • React : 起源于 Facebook 的內部項目, 因為該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設 Instagram 的網站。做出來以后,發現這套東西很好用,在2013年5月開源. 由于 React 的設計思想極其獨特,屬于革命性創新,性能出眾,代碼邏輯卻非常簡單。所以,越來越多的人開始關注和使用,認為它可能是將來 Web 開發的主流工具。
          • 簡單直觀、符合習慣的(idiomatic)方式去編程,讓代碼更容易被理解,從而易于維護和不斷演進。這正是React的設計哲學;
          • flex 布局 : 布局方式;
          • redux : JS 狀態容器,提供可預測化的狀態管理, 實現view & state 分離,開發體驗超爽, 而且體小精悍(只有2K);
          • immutable.js :“Pete Hunt: Shared mutable state is the root of all evil(共享的可變狀態是萬惡之源)”, 有人說 Immutable 可以給 React 應用帶來數十倍的提升,也有人說 Immutable 的引入是近期 JavaScript 中偉大的發明, Facebook 工程師 Lee Byron 花費 3 年時間打造,與 React 同期出現;
          • Immutable 詳解及 React 中實踐(https://github.com/camsong/blog/issues/3)。

          如何進行環境搭建

          • node.js RN的調試服務基于node服務器;
          • npm js包管理工具;
          • Yarn是Facebook提供的替代npm的工具,可以加速node模塊的下載。React Native的命令行工具用于執行創建、初始化、更新項目、運行打包服務(packager)等任務;
          • react-native 環境搭建(https://facebook.github.io/react-native/docs/getting-started.html)。

          如何進行UI繪制與布局

          React Native 提供豐富的基礎組件庫,使用Flexbox布局規則。采用jsx更直觀的表達用戶界面結構。

          import React, {Component} from 'react'
          import {View, Text, Button, StyleSheet} from 'react-native'
          export class Home extends Component {
           state={
           number: 0
           }
           _increase() {
           const { number }=this.state
           this.setState({number: number + 1})
           }
           _decrease() {
           const { number }=this.state
           this.setState({number: number - 1})
           }
           render() {
           const { number }=this.state
           return (
           <View style={styles.container}>
           <Text>Home</Text>
           <Button title="加" onPress={this._increase.bind(this)}/> 
           <Button title="減" onPress={this._decrease.bind(this)}/> 
           <Text>{number}</Text>
           </View>
           )
           }
          }
          let styles=StyleSheet.create({
           container: {
           flex: 1,
           backgroundColor: '#fff'
           }
          })
          

          上例繪制一個簡單的頁面, View是最基礎的UI組件,并且支持Flexbox布局,Text是用于顯示文本的組件,Button從命名上就可以明確是按鈕組件,StyleSheet 提供了一種類似 CSS 樣式表的抽象。

          調試

          調試是開發流程中最重要的事情,下面兩個工具給RN開發帶來了超爽的體驗

          • RN 調試工具:react-native-debugger
          • https://github.com/jhen0409/react-native-debugger
          • redux 開發擴展插件:redux-devtools-extension
          • https://github.com/zalmoxisus/redux-devtools-extension

          靜態代碼檢查

          JavaScript是解釋型語言,編譯過程只有詞法分析和語法分析,并沒有詞法檢查,eslint對于JS的意義格外重要:

          • 避免隱藏錯誤;
          • 代碼統一規范,提高可讀性。

          代碼質量的保證

          • redux unit test:對于actions & reduce校驗不可少(https://redux.js.org/docs/recipes/WritingTests.html);
          • Jest:很棒的BDD(https://facebook.github.io/jest/docs/en/tutorial-react-native.html,PS:每當發現一個工具特別好用的時候,發現都是Facebook開源的);
          • fetch-mock:異步單測不可少(http://www.wheresrhys.co.uk/fetch-mock/)。

          CI 可以用以下工具

          • travis-ci:GitHub最流行的CI工具之一(https://travis-ci.org/);
          • circle-ci:react-native GitHub庫使用的CI工具(https://circleci.com/);
          • gitlab-ci:目前我司用的是gitlab ci(https://about.gitlab.com/features/gitlab-ci-cd/)。

          轉場

          • tab-navigator框架:流暢的轉場動畫對于App體驗很重要;
          • react-navigation:RN社區今后主推的方案是一個單獨的導航庫react-navigation(https://reactnavigation.org/),它的使用十分簡單。性能上在原生線程上的Animated動畫庫,因而性能表現十分流暢,此外其動畫形式和手勢都非常便于定制。

          狀態管理

          • view與狀態分離:Redux由Flux演變而來,但受Elm的啟發,避開了Flux的復雜性。不管你有沒有使用過它們,只需幾分鐘就能上手Redux。
          • 單向數據流: 應用中所有的state都以一個對象樹的形式儲存在一個單一的store中。 惟一改變state的辦法是觸發action,一個描述發生什么的對象。為了描述action如何改變state樹,你需要編寫reducers。

          如何做網絡請求

          • 使用fetch(https://facebook.github.io/react-native/docs/network);
          fetch('https://mywebsite.com/endpoint/', {
           method: 'POST',
           headers: {
           Accept: 'application/json',
           'Content-Type': 'application/json',
           },
           body: JSON.stringify({
           firstParam: 'yourValue',
           secondParam: 'yourOtherValue',
           }),
          });
          
          • react-native-fetch-blob:更好的數據傳輸工具(https://github.com/wkh237/react-native-fetch-blob)。

          如何本地存儲

          • AsyncStorage:使用起來非常簡單的Key-Value Coding, 返回Promise;
          import { AsyncStorage } from 'react-native'
          let kLoginInfo='@login:info'
          //存儲
          AsyncStorage.setItem(kLoginInfo, JSON.stringify(loginInfo))
          //刪除
          AsyncStorage.removeItem(kLoginInfo)
          //加載
          AsyncStorage.getItem(kLoginInfo)
          
          • iOS內部是用一個json文件實現永久性存儲, Android方面據官方了解是會嘗試使用RocksDB,或退而選擇 SQLite;
          • 集成redux存儲(https://github.com/rt2zz/redux-persist);
          • 也可嘗試一下款平臺數據庫realm(https://realm.io/docs/javascript/latest/v)。

          熱更新

          • 這是React Native的一個重要功能,蘋果去年有過一次對熱修復的嚴打,JSPatch慘遭扼殺,不過對于RN這樣的沙盒熱更新是可以的;
          • 微軟的hot-push是個不錯的工具(https://github.com/Microsoft/react-native-code-push);
          • 有條件的單位可以自己建熱修復服務,下載bundle包。

          native組件開發

          • React Native可能還沒有相應的模塊封裝,但是提供native組件開發能力。利用這種方式解決平臺特性,支付、推送、Face ID都可以封裝成native組件來解決:
          • iOS原生模塊(https://reactnative.cn/docs/native-modules-ios)
          • iOS原生UI組件(https://reactnative.cn/docs/native-components-ios/)
          • 安卓原生模塊(https://reactnative.cn/docs/native-modules-android/)
          • 安卓原生UI組件(https://reactnative.cn/docs/native-components-android/)
          • rnstart:是根據上面技術棧搭建的react native starter demo工程(https://github.com/jeremyzj/rnstarter)。

          未來展望

          論成熟度、穩定性,RN 比不上iOS和Android原生,也存在很多奇怪的BUG,習慣了OC、Java語言開發的對于JS缺少類型系統很失望,對于手動操作動畫也依然無解,長列表性能問題無解、手勢操作不夠靈活、iOS podfile維護也不給力........等等問題。

          很多單位采用模塊化方案,讓App有RN的能力,讓業務交互簡單的模塊來用react-native開發。但是Facebook依然很努力地在改變,2018年對react-native有了一次大的重構,目的更輕量化并能更好地適應現有的原生應用,更符合JS的生態系統。

          對于移動開發者而言,react-native只是開發箱中其中一種工具。豐富自己工具箱,才能有更寬的視野和更多的開發思路。

          作者:魔笛,從事移動端開發7+年的經驗,目前在某互聯網金融公司作為iOS端leader工作。

          聲明:本文為作者投稿,版權歸對方所有。


          主站蜘蛛池模板: 国产精品亚洲一区二区无码| 国产精品福利一区二区久久| 成人国产精品一区二区网站公司| 一区二区视频在线免费观看| 国产福利电影一区二区三区久久老子无码午夜伦不 | 日韩社区一区二区三区| 亚洲制服中文字幕第一区| 国偷自产视频一区二区久| 日韩美一区二区三区| 亲子乱AV视频一区二区| 国产产一区二区三区久久毛片国语| 韩国美女vip福利一区| 无码国产精品一区二区免费式芒果| 一本色道久久综合一区| 亚洲AV网一区二区三区| 亚洲午夜在线一区| 亚洲日本精品一区二区| 国产裸体歌舞一区二区| 精品人妻一区二区三区毛片| 国产精品亚洲一区二区无码| 国产一区二区三区四| 中文字幕精品无码一区二区三区| 国产AV午夜精品一区二区三区| 一级毛片完整版免费播放一区 | 久久久久成人精品一区二区| 一区二区在线视频观看| 天堂不卡一区二区视频在线观看| V一区无码内射国产| 日韩视频在线观看一区二区| 自拍日韩亚洲一区在线| 无码日本电影一区二区网站| 日产一区日产2区| 麻豆一区二区在我观看| jizz免费一区二区三区| 成人精品一区二区三区电影| 插我一区二区在线观看| 最新中文字幕一区| 日韩人妻精品无码一区二区三区| 国产亚洲综合一区二区三区| 亚洲视频在线一区二区三区| 成人免费一区二区三区|